nex_docus/frontend/src/pages/Document/DocumentEditor.css

654 lines
15 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

@import '@/components/LargeMarkdownViewer/LargeMarkdownViewer.css';
.document-editor-page {
height: calc(100vh - 64px);
/* width: calc(100% + 32px); */
display: flex;
margin: -16px;
padding: 8px;
box-sizing: border-box;
background: var(--bg-color);
}
.document-editor-container {
height: 100%;
width: 100%;
display: flex;
flex: 1;
}
.document-sider {
border-right: 1px solid var(--border-color);
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
flex-shrink: 0;
background: var(--sider-bg);
}
/* 修复 Sider 内部 flex 布局 */
.document-sider .ant-layout-sider-children {
display: flex;
flex-direction: column;
height: 100%;
}
.sider-header {
padding: 12px 10px 12px;
border-bottom: 1px solid var(--border-color);
display: flex;
flex-direction: column;
gap: 10px;
background: var(--header-bg);
}
.sider-header h2 {
margin: 0;
font-size: 20px;
font-weight: 700;
letter-spacing: 0;
color: var(--text-color);
line-height: 1.1;
}
.sider-title-row {
display: flex;
align-items: center;
gap: 14px;
min-width: 0;
}
.sider-title-row h2 {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.project-back-button {
width: 28px;
height: 28px;
border: none;
border-radius: 999px;
display: inline-flex;
align-items: center;
justify-content: center;
background: transparent;
color: var(--text-color-secondary);
font-size: 16px;
cursor: pointer;
flex-shrink: 0;
transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.project-back-button:hover {
background: var(--item-hover-bg);
color: var(--text-color);
transform: translateX(-1px);
}
.project-back-button:focus-visible {
outline: 2px solid rgba(22, 119, 255, 0.35);
outline-offset: 2px;
}
.sider-actions {
display: flex;
align-items: center;
}
.mode-actions-row {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.mode-actions-group {
display: inline-flex;
align-items: center;
}
.sider-actions .mode-actions-group .ant-btn {
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
color: var(--text-color-secondary);
}
.sider-actions .mode-actions-group .ant-btn:hover {
background: var(--item-hover-bg);
border-color: var(--border-color);
color: var(--link-color);
}
.document-content {
height: 100%;
width: 100%;
background: var(--bg-color);
display: flex;
flex-direction: column;
flex: 1;
min-width: 0;
}
/* 强制覆盖 Ant Design Content 的默认样式 */
.document-editor-container .ant-layout-content {
display: flex !important;
flex-direction: column !important;
flex: 1 !important;
min-width: 0 !important;
width: 100% !important;
}
.content-header {
padding: 16px 24px;
min-height: 57px;
border-bottom: 1px solid var(--border-color);
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
background: var(--header-bg);
flex-shrink: 0;
}
.editor-container {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
min-width: 0;
overflow: hidden;
width: 100%;
}
.bytemd-wrapper {
flex: 1;
display: flex;
flex-direction: column;
/* Changed to column to force child stretch width */
min-height: 0;
min-width: 0;
overflow: hidden;
width: 100%;
height: 100%;
padding: 5px 10px;
}
.bytemd-wrapper.large-file-editor {
position: relative;
display: flex;
flex-direction: column;
}
/* Fix for bytemd-react wrapper div(仅普通编辑器,超大着色编辑器不受此约束) */
.bytemd-wrapper:not(.large-file-editor)>div {
flex: 1;
display: flex;
flex-direction: column;
width: 100% !important;
height: 100% !important;
min-width: 0;
}
.empty-editor {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-color-secondary);
}
/* 文件夹视图滚动容器(复用浏览模式 docs-folder-* 布局,仅新增滚动) */
.editor-folder-scroll {
flex: 1;
min-height: 0;
min-width: 0;
overflow-y: auto;
width: 100%;
}
/* PDF 只读预览(编辑模式下内置,与浏览模式一致) */
.pdf-editor-container {
flex: 1;
min-height: 0;
min-width: 0;
display: flex;
flex-direction: column;
overflow: hidden;
width: 100%;
height: 100%;
background: var(--bg-color);
}
.pdf-header-toolbar {
min-width: 0;
overflow-x: auto;
overflow-y: hidden;
}
.pdf-header-toolbar .pdf-toolbar {
white-space: nowrap;
}
/* ByteMD 编辑器样式覆盖 */
.bytemd {
width: 100% !important;
height: 100% !important;
display: flex !important;
flex-direction: column !important;
border: 1px solid var(--border-color);
border-radius: 2px;
overflow: hidden;
max-width: none !important;
/* Ensure no max-width constraint */
box-sizing: border-box;
background-color: var(--bg-color);
color: var(--text-color);
}
/* 工具栏样式 */
.bytemd-toolbar {
flex-shrink: 0;
border-bottom: 1px solid var(--border-color);
background-color: var(--toolbar-bg);
box-sizing: border-box;
color: var(--text-color);
}
.bytemd-toolbar-icon {
color: var(--text-color);
}
.bytemd-toolbar-icon:hover {
background-color: var(--item-hover-bg);
}
/* ByteMD 内置的右侧按钮:1=目录 2=帮助 3=仅编辑 4=仅预览 5=全屏 6=源代码。
1/2 依赖预览区渲染,3/4 与页面自身的「编辑 / 分栏 / 预览」分段控件重复,统一隐藏;
5 由页面自绘、并入同一分段控件的「全屏」取代(DOM 仍保留,靠它驱动 ByteMD 的全屏状态);
6「源代码」是 ByteMD 指向项目主页的外链,不属于文档编辑操作,编辑模式下统一去掉。
隐藏后右侧只剩页面 Portal 注入的统一视图控件。
注意:页面用 Portal 把分段控件插到 .bytemd-toolbar-right 的最后一个子节点,
上面的序号才不会被错位,改动插入位置时记得同步这里的 nth-child。 */
.bytemd-toolbar-right .bytemd-toolbar-icon:nth-child(-n+6) {
display: none;
}
/* 工具栏右侧改成 flex,让「编辑 / 分栏 / 预览」和内置图标同一行居中对齐 */
.bytemd-toolbar-right {
display: flex;
align-items: center;
}
/* 视图模式切换(Portal 注入):编辑 / 分栏 / 预览 / 全屏 合成同一分段控件,
ByteMD 自带图标已全部隐藏,它成为工具栏右侧唯一的控件 */
.bytemd-toolbar-right .view-mode-switch {
order: -1;
line-height: 1;
}
/* 让单个选项与右侧 24px 图标按钮同高,整条控件不会把工具栏撑高 */
.bytemd-toolbar-right .view-mode-switch .ant-segmented-item-label {
display: flex;
align-items: center;
justify-content: center;
min-height: 20px;
padding-inline: 7px;
}
.bytemd-toolbar-right .view-mode-switch .view-mode-option {
display: inline-flex;
align-items: center;
font-size: 14px;
}
/* 全屏是开关动作而非视图选项:用主色区分「已进入全屏」,图标同时切换为退出样式 */
.bytemd-toolbar-right .view-mode-switch .view-mode-option.is-active {
color: var(--color-primary);
}
/* 预览模式是只读视图:隐藏会改动源码的 Markdown 工具栏,以及失效的同步滚动开关 */
.bytemd-wrapper[data-view-mode="preview"] .bytemd-toolbar-left {
display: none;
}
.bytemd-wrapper:not([data-view-mode="split"]) .bytemd-status-right label {
display: none;
}
/* 视图模式:编辑器始终以 split 渲染(保证 Markdown 工具栏可用),
通过显隐控制编辑区/预览区,覆盖 ByteMD 写死的 width:50% 内联样式。 */
.bytemd-wrapper[data-view-mode="edit"] .bytemd-editor,
.bytemd-wrapper[data-view-mode="preview"] .bytemd-preview {
width: 100% !important;
}
.bytemd-wrapper[data-view-mode="edit"] .bytemd-preview,
.bytemd-wrapper[data-view-mode="preview"] .bytemd-editor {
display: none !important;
}
/* 头部右侧操作区(视图模式切换已移入编辑器工具栏) */
.content-header-actions {
align-items: center;
flex-wrap: wrap;
justify-content: flex-end;
}
/* 保存按钮:自动保存开关融合在按钮内部,整体呈现为一个主色按钮
左半边「保存」执行保存,右半边「自动保存」开关切换自动保存 */
.save-control {
display: inline-flex;
align-items: stretch;
height: 32px;
border-radius: var(--radius-sm);
background: var(--color-primary);
color: var(--text-color-inverse);
overflow: hidden;
transition: background var(--transition-fast);
}
.save-control:hover {
background: var(--color-primary-hover);
}
.save-control-main {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 0 12px;
border: 0;
background: transparent;
color: inherit;
font-size: 14px;
line-height: 1;
cursor: pointer;
transition: background var(--transition-fast);
}
.save-control-main:hover:not(:disabled) {
background: rgba(255, 255, 255, 0.14);
}
.save-control-main:disabled {
cursor: not-allowed;
opacity: 0.6;
}
.save-control-sep {
align-self: center;
width: 1px;
height: 16px;
background: rgba(255, 255, 255, 0.35);
}
.save-control-auto {
display: inline-flex;
align-items: center;
padding: 0 10px;
cursor: pointer;
user-select: none;
transition: background var(--transition-fast);
}
.save-control-auto:hover {
background: rgba(255, 255, 255, 0.14);
}
/* 开关本身不单独响应点击,由外层整块统一处理,避免重复触发 */
.save-control-auto .ant-switch {
pointer-events: none;
}
/* 主色按钮上的开关重新配色:开关内直接显示「自动 / 手动」,开 / 关都清晰可辨 */
.save-control-auto .ant-switch {
background: rgba(0, 0, 0, 0.28);
/* antd 默认宽度放不下两个汉字,会折行/裁切,这里给足文本空间 */
min-width: 58px;
}
.save-control-auto .ant-switch .ant-switch-handle::before {
background: #fff;
}
.save-control-auto .ant-switch.ant-switch-checked {
background: #fff;
}
/* antd 把颜色写在子节点上,必须直接覆盖 checked / unchecked 文本,否则白字压白底看不见 */
.save-control-auto .ant-switch .ant-switch-inner-checked,
.save-control-auto .ant-switch .ant-switch-inner-unchecked {
color: #fff;
font-size: 12px;
white-space: nowrap;
}
.save-control-auto .ant-switch.ant-switch-checked .ant-switch-inner-checked {
color: var(--color-primary);
}
.save-control-auto .ant-switch.ant-switch-checked .ant-switch-handle::before {
background: var(--color-primary);
}
/* 编辑器工具栏里的视图模式图标(文案放在 Tooltip 中) */
.view-mode-option {
display: inline-flex;
align-items: center;
line-height: 1;
}
.editor-floating-toc {
z-index: 20;
}
/* ByteMD 全屏:position: fixed 但没写 z-index,会被 ModeSwitch(z-index:1) 等浮层压住,
导致左侧项目树的操作按钮浮现在全屏编辑器上;这里显式抬到悬浮层。 */
.bytemd-fullscreen.bytemd {
z-index: var(--z-float);
}
/* 全屏时文档索引浮标要跟着抬一层,保证仍在全屏编辑器之上可点 */
.bytemd-wrapper:has(.bytemd-fullscreen) .editor-floating-toc {
z-index: calc(var(--z-float) + 1);
}
/* 编辑和预览区域容器 */
.bytemd-body {
flex: 1 !important;
display: flex !important;
overflow: hidden;
min-height: 0;
width: 100% !important;
box-sizing: border-box;
/* Added for consistent box model */
min-width: 0;
/* Prevent flex item from overflowing */
background-color: var(--bg-color);
}
/* 编辑区域 - 默认分栏,保留 Bytemd 内联样式对仅编辑/仅预览的控制 */
.bytemd-editor {
overflow: hidden;
min-height: 0;
box-sizing: border-box;
/* Added for consistent box model */
min-width: 0;
/* Prevent flex item from overflowing */
background-color: var(--bg-color);
}
.bytemd-wrapper[data-view-mode="split"] .bytemd-editor {
border-right: 1px solid var(--border-color);
}
/* 预览区域 - 默认分栏,保留 Bytemd 内联样式对仅编辑/仅预览的控制 */
.bytemd-preview {
overflow-y: auto !important;
overflow-x: hidden !important;
padding: 16px;
font-size: 14px;
line-height: 1.8;
box-sizing: border-box;
/* Added for consistent box model */
min-width: 0;
/* Prevent flex item from overflowing */
background-color: var(--bg-color);
color: var(--text-color);
}
/* CodeMirror 容器 */
.bytemd-editor .CodeMirror {
flex: 1;
min-height: 0;
font-size: 14px;
line-height: 1.8;
width: 100%;
height: 100%;
background-color: var(--bg-color);
color: var(--text-color);
}
/* CodeMirror 滚动容器 */
.bytemd-editor .CodeMirror-scroll {
overflow-y: scroll !important;
overflow-x: auto !important;
min-height: 100% !important;
height: 100% !important;
}
/* 预览区域的markdown样式 */
.bytemd-preview h1,
.bytemd-preview h2,
.bytemd-preview h3,
.bytemd-preview h4,
.bytemd-preview h5,
.bytemd-preview h6 {
margin-top: 24px;
margin-bottom: 16px;
font-weight: 600;
line-height: 1.25;
color: var(--text-color);
}
.bytemd-preview h1 {
font-size: 2em;
border-bottom: 1px solid var(--border-color);
padding-bottom: 0.3em;
}
.bytemd-preview h2 {
font-size: 1.5em;
border-bottom: 1px solid var(--border-color);
padding-bottom: 0.3em;
}
.bytemd-preview p {
margin-bottom: 16px;
color: var(--text-color);
}
.bytemd-preview code {
padding: 0.2em 0.4em;
margin: 0;
font-size: 85%;
background-color: var(--code-bg);
border-radius: 3px;
color: var(--text-color);
}
.bytemd-preview pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: var(--code-bg);
border-radius: 3px;
margin-bottom: 16px;
}
.bytemd-preview pre code {
display: inline;
padding: 0;
margin: 0;
overflow: visible;
line-height: inherit;
background-color: transparent;
border: 0;
color: inherit;
}
.bytemd-preview img {
max-width: 100%;
box-sizing: content-box;
}
.bytemd-preview table {
border-collapse: collapse;
border-spacing: 0;
margin-bottom: 16px;
}
.bytemd-preview table th,
.bytemd-preview table td {
padding: 6px 13px;
border: 1px solid var(--table-border-color);
color: var(--text-color);
}
.bytemd-preview table th {
font-weight: 600;
background-color: var(--table-header-bg);
}
.bytemd-preview blockquote {
margin: 0 0 16px;
padding: 0 1em;
color: var(--blockquote-text-color);
border-left: 0.25em solid var(--blockquote-border-color);
}
.bytemd-preview ul,
.bytemd-preview ol {
padding-left: 2em;
margin-bottom: 16px;
color: var(--text-color);
}
.bytemd-preview li {
margin-bottom: 0.25em;
}
.content-header .preview-header-title {
flex: 1;
min-width: 0;
max-width: none;
}
@media (max-width: 768px) {
.document-editor-page {
padding: 8px;
}
}
/* 未保存改动标记:与保存按钮同处内容区右上角,弱化但可辨识 */
.content-header-actions .unsaved-badge {
display: inline-flex;
align-items: center;
height: 22px;
padding: 0 var(--space-xs);
font-size: 12px;
line-height: 1;
color: var(--color-warning);
background: var(--color-warning-bg);
border: 1px solid var(--color-warning);
border-radius: var(--radius-pill);
}