refactor(module-management): R2c 表单设计面板 UI 归一
- 字段库搜索/占位符/栅格宽度/文本域高度输入 → ui Input(change 载荷改为值) - 编辑方式切换 → ui RadioGroup;设计/数据视图切换 → ui Tabs(nav-only) - 帮助气泡 → ui Popover(hover),删除自绘 help-pop/.mm-edit__help 样式 - 属性面板折叠/展开钮 → ui Button;状态开关×4 → ui Switch - 分组名称内联编辑 → ui Input;确认/取消/齿轮/删除 → ui Button(type=ghost) - 删除废弃 .mm-fdesign__toggle、.mm-edit__mode-btn、.mm-edit__view-btn 样式 - 适配 .mm-edit__mode / .mm-edit__view-switch 为紧凑字号 - 所有 Button 覆写样式加 .button 后缀(确保覆盖 ui Button 默认尺寸) - 所有 Input 覆写样式加 .input-wrapper 后缀 - 替换 .mm-fdesign__span-control input[type=number] 为 .mm-fdesign__span-input.input-wrapper
This commit is contained in:
1 parent
8c506ae56c
commit
76b12cc5e1
1 file changed
+142
-323
+142
-323
@@ -26,8 +26,13 @@ import draggable from 'vuedraggable'
|
|||||||
import {
|
import {
|
||||||
Message,
|
Message,
|
||||||
Button,
|
Button,
|
||||||
Select,
|
|
||||||
Input,
|
Input,
|
||||||
|
Popover,
|
||||||
|
Radio,
|
||||||
|
RadioGroup,
|
||||||
|
Select,
|
||||||
|
Switch,
|
||||||
|
Tabs,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
DatePicker,
|
DatePicker,
|
||||||
Form,
|
Form,
|
||||||
@@ -1306,12 +1311,12 @@ function onColspanChange(value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 数字输入框 change(失焦/回车)提交:与原值不同才真正写入
|
// 数字输入框 change(失焦/回车)提交:与原值不同才真正写入
|
||||||
function onColspanInput(event) {
|
function onColspanInput(value) {
|
||||||
const row = selectedRow.value
|
const row = selectedRow.value
|
||||||
if (!row || props.loading) return
|
if (!row || props.loading) return
|
||||||
const value = Math.min(24, Math.max(1, Number(event.target.value) || 24))
|
const next = Math.min(24, Math.max(1, Number(value) || 24))
|
||||||
if (value === spanOf(row)) return
|
if (next === spanOf(row)) return
|
||||||
onColspanChange(value)
|
onColspanChange(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onHeightChange(value) {
|
function onHeightChange(value) {
|
||||||
@@ -1322,12 +1327,12 @@ function onHeightChange(value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 占位符:change(失焦/回车)提交,有变化才真正写入 */
|
/* 占位符:change(失焦/回车)提交,有变化才真正写入 */
|
||||||
function onPlaceholderChange(event) {
|
function onPlaceholderChange(value) {
|
||||||
const row = selectedRow.value
|
const row = selectedRow.value
|
||||||
if (!row || props.loading) return
|
if (!row || props.loading) return
|
||||||
const value = event.target.value.trim()
|
const next = String(value ?? '').trim()
|
||||||
if ((row.b_placeholder || '') === value) return
|
if ((row.b_placeholder || '') === next) return
|
||||||
row.b_placeholder = value || null
|
row.b_placeholder = next || null
|
||||||
emitUpdate()
|
emitUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1424,12 +1429,7 @@ onBeforeUnmount(() => {
|
|||||||
:class="{ 'is-inspector-collapsed': inspectorCollapsed }"
|
:class="{ 'is-inspector-collapsed': inspectorCollapsed }"
|
||||||
>
|
>
|
||||||
<aside class="mm-fdesign__lib" aria-label="字段列表">
|
<aside class="mm-fdesign__lib" aria-label="字段列表">
|
||||||
<input
|
<Input v-model="libSearch" class="mm-fdesign__lib-search" placeholder="搜索字段名 / 编码" />
|
||||||
v-model="libSearch"
|
|
||||||
class="mm-fdesign__lib-search"
|
|
||||||
type="text"
|
|
||||||
placeholder="搜索字段名 / 编码"
|
|
||||||
/>
|
|
||||||
<div class="mm-fdesign__lib-group">
|
<div class="mm-fdesign__lib-group">
|
||||||
<draggable
|
<draggable
|
||||||
class="mm-fdesign__lib-list"
|
class="mm-fdesign__lib-list"
|
||||||
@@ -1475,50 +1475,30 @@ onBeforeUnmount(() => {
|
|||||||
<div class="mm-fdesign__main">
|
<div class="mm-fdesign__main">
|
||||||
<div class="mm-edit__head">
|
<div class="mm-edit__head">
|
||||||
<div class="mm-edit__head-left">
|
<div class="mm-edit__head-left">
|
||||||
<div class="mm-edit__mode" role="group" aria-label="编辑方式">
|
<RadioGroup
|
||||||
<button
|
class="mm-edit__mode"
|
||||||
type="button"
|
role="group"
|
||||||
class="mm-edit__mode-btn"
|
aria-label="编辑方式"
|
||||||
:class="{ 'is-active': (editMode || 'form') === 'form' }"
|
:model-value="editMode || 'form'"
|
||||||
title="主表:以表单形式编辑"
|
:disabled="loading"
|
||||||
:disabled="loading"
|
@update:model-value="onEditModeChange"
|
||||||
@click="onEditModeChange('form')"
|
>
|
||||||
>
|
<Radio value="form" title="主表:以表单形式编辑">主表表单</Radio>
|
||||||
主表表单
|
<Radio value="table" title="子表:以表格形式编辑">子表表格</Radio>
|
||||||
</button>
|
</RadioGroup>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="mm-edit__mode-btn"
|
|
||||||
:class="{ 'is-active': (editMode || 'form') === 'table' }"
|
|
||||||
title="子表:以表格形式编辑"
|
|
||||||
:disabled="loading"
|
|
||||||
@click="onEditModeChange('table')"
|
|
||||||
>
|
|
||||||
子表表格
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mm-edit__head-center">
|
<div class="mm-edit__head-center">
|
||||||
<div class="mm-edit__view-switch" role="tablist" aria-label="视图切换">
|
<Tabs
|
||||||
<button
|
class="mm-edit__view-switch"
|
||||||
type="button"
|
nav-only
|
||||||
class="mm-edit__view-btn"
|
:items="[
|
||||||
:class="{ 'is-active': viewMode === 'design' }"
|
{ key: 'design', label: '设计' },
|
||||||
data-view="design"
|
{ key: 'data', label: '数据' },
|
||||||
@click="switchView('design')"
|
]"
|
||||||
>
|
:model-value="viewMode"
|
||||||
设计
|
aria-label="视图切换"
|
||||||
</button>
|
@update:model-value="switchView"
|
||||||
<button
|
/>
|
||||||
type="button"
|
|
||||||
class="mm-edit__view-btn"
|
|
||||||
:class="{ 'is-active': viewMode === 'data' }"
|
|
||||||
data-view="data"
|
|
||||||
@click="switchView('data')"
|
|
||||||
>
|
|
||||||
数据
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mm-edit__head-right">
|
<div class="mm-edit__head-right">
|
||||||
<Button type="outline" :disabled="loading" @click="addGroup">
|
<Button type="outline" :disabled="loading" @click="addGroup">
|
||||||
@@ -1527,9 +1507,11 @@ onBeforeUnmount(() => {
|
|||||||
<Button type="ghost" :disabled="loading" @click="previewOpen = true">
|
<Button type="ghost" :disabled="loading" @click="previewOpen = true">
|
||||||
<Eye :size="14" /> 预览
|
<Eye :size="14" /> 预览
|
||||||
</Button>
|
</Button>
|
||||||
<div class="mm-edit__help">
|
<Popover trigger="hover" placement="bottom-end" :arrow="false" :offset="8">
|
||||||
<span class="mm-edit__help-icon" aria-hidden="true">?</span>
|
<template #trigger>
|
||||||
<div class="mm-edit__help-pop">
|
<span class="mm-edit__help-icon" aria-hidden="true">?</span>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
<div class="mm-edit__help-title">快捷键</div>
|
<div class="mm-edit__help-title">快捷键</div>
|
||||||
<ul class="mm-edit__help-list">
|
<ul class="mm-edit__help-list">
|
||||||
<li><kbd>Ctrl+C</kbd> 复制选中字段属性</li>
|
<li><kbd>Ctrl+C</kbd> 复制选中字段属性</li>
|
||||||
@@ -1537,8 +1519,8 @@ onBeforeUnmount(() => {
|
|||||||
<li><kbd>Ctrl+V</kbd> 粘贴属性到选中字段</li>
|
<li><kbd>Ctrl+V</kbd> 粘贴属性到选中字段</li>
|
||||||
<li><kbd>Delete</kbd> 删除选中字段</li>
|
<li><kbd>Delete</kbd> 删除选中字段</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1584,7 +1566,7 @@ onBeforeUnmount(() => {
|
|||||||
<GripVertical :size="13" />
|
<GripVertical :size="13" />
|
||||||
</button>
|
</button>
|
||||||
<template v-if="editingGroupKey === section.key">
|
<template v-if="editingGroupKey === section.key">
|
||||||
<input
|
<Input
|
||||||
ref="sectionEditInput"
|
ref="sectionEditInput"
|
||||||
v-model="groupTitleDraft"
|
v-model="groupTitleDraft"
|
||||||
class="mm-fdesign__section-edit"
|
class="mm-fdesign__section-edit"
|
||||||
@@ -1596,24 +1578,24 @@ onBeforeUnmount(() => {
|
|||||||
@blur="commitEditGroupTitle(section)"
|
@blur="commitEditGroupTitle(section)"
|
||||||
/>
|
/>
|
||||||
<span class="mm-fdesign__section-edit-actions">
|
<span class="mm-fdesign__section-edit-actions">
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="ghost"
|
||||||
class="mm-fdesign__section-edit-btn"
|
class="mm-fdesign__section-edit-btn"
|
||||||
title="确认"
|
title="确认"
|
||||||
aria-label="确认修改分组名"
|
aria-label="确认修改分组名"
|
||||||
@mousedown.prevent="commitEditGroupTitle(section)"
|
@mousedown.prevent="commitEditGroupTitle(section)"
|
||||||
>
|
>
|
||||||
<Check :size="13" />
|
<Check :size="13" />
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="ghost"
|
||||||
class="mm-fdesign__section-edit-btn"
|
class="mm-fdesign__section-edit-btn"
|
||||||
title="取消"
|
title="取消"
|
||||||
aria-label="取消修改分组名"
|
aria-label="取消修改分组名"
|
||||||
@mousedown.prevent="cancelEditGroupTitle"
|
@mousedown.prevent="cancelEditGroupTitle"
|
||||||
>
|
>
|
||||||
<X :size="13" />
|
<X :size="13" />
|
||||||
</button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@@ -1631,25 +1613,25 @@ onBeforeUnmount(() => {
|
|||||||
@click.stop="startEditGroupTitle(section)"
|
@click.stop="startEditGroupTitle(section)"
|
||||||
>空</span>
|
>空</span>
|
||||||
<span class="mm-edit__section-meta">
|
<span class="mm-edit__section-meta">
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="ghost"
|
||||||
class="mm-fdesign__section-btn"
|
class="mm-fdesign__section-btn"
|
||||||
title="分组设置"
|
title="分组设置"
|
||||||
aria-label="分组设置"
|
aria-label="分组设置"
|
||||||
@click.stop="openSectionSettings(section)"
|
@click.stop="openSectionSettings(section)"
|
||||||
>
|
>
|
||||||
<Settings2 :size="13" />
|
<Settings2 :size="13" />
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button
|
||||||
v-if="section.group"
|
v-if="section.group"
|
||||||
type="button"
|
type="ghost"
|
||||||
class="mm-fdesign__section-del"
|
class="mm-fdesign__section-del"
|
||||||
title="删除分组(其下字段移至未分组)"
|
title="删除分组(其下字段移至未分组)"
|
||||||
aria-label="删除分组"
|
aria-label="删除分组"
|
||||||
@click.stop="deleteGroupDirect(section)"
|
@click.stop="deleteGroupDirect(section)"
|
||||||
>
|
>
|
||||||
<Trash2 :size="13" />
|
<Trash2 :size="13" />
|
||||||
</button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -1741,15 +1723,15 @@ onBeforeUnmount(() => {
|
|||||||
<EyeOff v-else :size="12" />
|
<EyeOff v-else :size="12" />
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="ghost"
|
||||||
class="mm-fdesign__tool-btn is-danger"
|
class="mm-fdesign__tool-btn is-danger"
|
||||||
title="删除字段"
|
title="删除字段"
|
||||||
aria-label="删除字段"
|
aria-label="删除字段"
|
||||||
@click.stop="removeRow(row)"
|
@click.stop="removeRow(row)"
|
||||||
>
|
>
|
||||||
<Trash2 :size="12" />
|
<Trash2 :size="12" />
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div class="mm-fdesign__field-control">
|
<div class="mm-fdesign__field-control">
|
||||||
<input
|
<input
|
||||||
@@ -1865,30 +1847,30 @@ onBeforeUnmount(() => {
|
|||||||
:class="{ 'is-collapsed': inspectorCollapsed }"
|
:class="{ 'is-collapsed': inspectorCollapsed }"
|
||||||
aria-label="属性面板"
|
aria-label="属性面板"
|
||||||
>
|
>
|
||||||
<button
|
<Button
|
||||||
v-if="inspectorCollapsed"
|
v-if="inspectorCollapsed"
|
||||||
type="button"
|
type="ghost"
|
||||||
class="mm-fdesign__panel-expand"
|
class="mm-fdesign__panel-expand"
|
||||||
title="展开属性面板"
|
title="展开属性面板"
|
||||||
aria-label="展开属性面板"
|
aria-label="展开属性面板"
|
||||||
@click="inspectorCollapsed = false"
|
@click="inspectorCollapsed = false"
|
||||||
>
|
>
|
||||||
<PanelRightOpen :size="14" />
|
<PanelRightOpen :size="14" />
|
||||||
</button>
|
</Button>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="mm-fdesign__subhead">
|
<div class="mm-fdesign__subhead">
|
||||||
<strong>属性</strong>
|
<strong>属性</strong>
|
||||||
<span class="mm-fdesign__subhead-meta">
|
<span class="mm-fdesign__subhead-meta">
|
||||||
<span>{{ selectedRow ? fieldName(selectedRow) : '未选中字段' }}</span>
|
<span>{{ selectedRow ? fieldName(selectedRow) : '未选中字段' }}</span>
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="ghost"
|
||||||
class="mm-fdesign__collapse"
|
class="mm-fdesign__collapse"
|
||||||
title="折叠属性面板"
|
title="折叠属性面板"
|
||||||
aria-label="折叠属性面板"
|
aria-label="折叠属性面板"
|
||||||
@click="inspectorCollapsed = true"
|
@click="inspectorCollapsed = true"
|
||||||
>
|
>
|
||||||
<PanelRightClose :size="13" />
|
<PanelRightClose :size="13" />
|
||||||
</button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="selectedRow">
|
<template v-if="selectedRow">
|
||||||
@@ -1903,12 +1885,11 @@ onBeforeUnmount(() => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="mm-fdesign__prop mm-fdesign__prop--full">
|
<div class="mm-fdesign__prop mm-fdesign__prop--full">
|
||||||
<label for="mm-fdesign-placeholder">占位符</label>
|
<label for="mm-fdesign-placeholder">占位符</label>
|
||||||
<input
|
<Input
|
||||||
id="mm-fdesign-placeholder"
|
id="mm-fdesign-placeholder"
|
||||||
class="mm-fdesign__prop-input"
|
class="mm-fdesign__prop-input"
|
||||||
type="text"
|
|
||||||
maxlength="100"
|
maxlength="100"
|
||||||
:value="selectedRow.b_placeholder || ''"
|
:model-value="selectedRow.b_placeholder || ''"
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
placeholder="输入框内的浅色提示文字"
|
placeholder="输入框内的浅色提示文字"
|
||||||
@change="onPlaceholderChange"
|
@change="onPlaceholderChange"
|
||||||
@@ -1922,12 +1903,11 @@ onBeforeUnmount(() => {
|
|||||||
>
|
>
|
||||||
<label for="mm-fdesign-colspan">栅格宽度</label>
|
<label for="mm-fdesign-colspan">栅格宽度</label>
|
||||||
<div class="mm-fdesign__span-control">
|
<div class="mm-fdesign__span-control">
|
||||||
<input
|
<Input
|
||||||
id="mm-fdesign-colspan"
|
id="mm-fdesign-colspan"
|
||||||
type="number"
|
type="number"
|
||||||
min="1"
|
class="mm-fdesign__span-input"
|
||||||
max="24"
|
:model-value="spanOf(selectedRow)"
|
||||||
:value="spanOf(selectedRow)"
|
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
aria-label="栅格宽度"
|
aria-label="栅格宽度"
|
||||||
@change="onColspanInput"
|
@change="onColspanInput"
|
||||||
@@ -1944,14 +1924,13 @@ onBeforeUnmount(() => {
|
|||||||
:options="TEXTAREA_HEIGHT_OPTIONS"
|
:options="TEXTAREA_HEIGHT_OPTIONS"
|
||||||
@update:model-value="onHeightChange"
|
@update:model-value="onHeightChange"
|
||||||
/>
|
/>
|
||||||
<input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
min="64"
|
class="mm-fdesign__span-input"
|
||||||
max="480"
|
:model-value="heightOf(selectedRow)"
|
||||||
:value="heightOf(selectedRow)"
|
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
aria-label="自定义文本域高度"
|
aria-label="自定义文本域高度"
|
||||||
@change="(event) => onHeightChange(event.target.value)"
|
@change="onHeightChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1960,47 +1939,35 @@ onBeforeUnmount(() => {
|
|||||||
<div class="mm-fdesign__toggles">
|
<div class="mm-fdesign__toggles">
|
||||||
<div class="mm-fdesign__toggle-line">
|
<div class="mm-fdesign__toggle-line">
|
||||||
<span>必填</span>
|
<span>必填</span>
|
||||||
<button
|
<Switch
|
||||||
type="button"
|
:model-value="Number(selectedRow.b_required) === 1"
|
||||||
class="mm-fdesign__toggle"
|
|
||||||
:class="{ 'is-on': Number(selectedRow.b_required) === 1 }"
|
|
||||||
:aria-pressed="Number(selectedRow.b_required) === 1"
|
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
@click="toggleInspector('b_required')"
|
@update:model-value="() => toggleInspector('b_required')"
|
||||||
></button>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mm-fdesign__toggle-line">
|
<div class="mm-fdesign__toggle-line">
|
||||||
<span>只读</span>
|
<span>只读</span>
|
||||||
<button
|
<Switch
|
||||||
type="button"
|
:model-value="Number(selectedRow.b_readonly) === 1"
|
||||||
class="mm-fdesign__toggle"
|
|
||||||
:class="{ 'is-on': Number(selectedRow.b_readonly) === 1 }"
|
|
||||||
:aria-pressed="Number(selectedRow.b_readonly) === 1"
|
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
@click="toggleInspector('b_readonly')"
|
@update:model-value="() => toggleInspector('b_readonly')"
|
||||||
></button>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mm-fdesign__toggle-line">
|
<div class="mm-fdesign__toggle-line">
|
||||||
<span>禁用</span>
|
<span>禁用</span>
|
||||||
<button
|
<Switch
|
||||||
type="button"
|
:model-value="Number(selectedRow.b_disabled) === 1"
|
||||||
class="mm-fdesign__toggle"
|
|
||||||
:class="{ 'is-on': Number(selectedRow.b_disabled) === 1 }"
|
|
||||||
:aria-pressed="Number(selectedRow.b_disabled) === 1"
|
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
@click="toggleInspector('b_disabled')"
|
@update:model-value="() => toggleInspector('b_disabled')"
|
||||||
></button>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mm-fdesign__toggle-line">
|
<div class="mm-fdesign__toggle-line">
|
||||||
<span>显示</span>
|
<span>显示</span>
|
||||||
<button
|
<Switch
|
||||||
type="button"
|
:model-value="Number(selectedRow.b_visible) === 1"
|
||||||
class="mm-fdesign__toggle"
|
|
||||||
:class="{ 'is-on': Number(selectedRow.b_visible) === 1 }"
|
|
||||||
:aria-pressed="Number(selectedRow.b_visible) === 1"
|
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
@click="toggleInspector('b_visible')"
|
@update:model-value="() => toggleInspector('b_visible')"
|
||||||
></button>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mm-fdesign__prop-group">操作</div>
|
<div class="mm-fdesign__prop-group">操作</div>
|
||||||
@@ -2248,82 +2215,17 @@ onBeforeUnmount(() => {
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 编辑方式:ui RadioGroup(紧凑字号) */
|
||||||
.mm-edit__mode {
|
.mm-edit__mode {
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 3px;
|
|
||||||
padding: 3px;
|
|
||||||
border: 1px solid var(--fms-border);
|
|
||||||
border-radius: var(--fms-control-radius);
|
|
||||||
background: var(--fms-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 编辑方式分段按钮(主表表单 / 子表表格) */
|
|
||||||
.mm-edit__mode-btn {
|
|
||||||
height: 26px;
|
|
||||||
padding: 0 12px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: transparent;
|
|
||||||
color: var(--fms-text-secondary);
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
white-space: nowrap;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&.is-active {
|
|
||||||
background: var(--fms-card);
|
|
||||||
color: var(--fms-text);
|
|
||||||
font-weight: 600;
|
|
||||||
box-shadow: 0 1px 3px rgba(30, 45, 64, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 视图切换:ui Tabs nav-only */
|
||||||
.mm-edit__view-switch {
|
.mm-edit__view-switch {
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 3px;
|
|
||||||
padding: 3px;
|
|
||||||
border: 1px solid var(--fms-border);
|
|
||||||
border-radius: var(--fms-control-radius);
|
|
||||||
background: var(--fms-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.mm-edit__view-btn {
|
|
||||||
height: 26px;
|
|
||||||
padding: 0 12px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: transparent;
|
|
||||||
color: var(--fms-text-secondary);
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&.is-active {
|
|
||||||
background: var(--fms-card);
|
|
||||||
color: var(--fms-text);
|
|
||||||
font-weight: 600;
|
|
||||||
box-shadow: 0 1px 3px rgba(30, 45, 64, 0.12);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- 快捷键帮助(右上角 ? 图标,hover 展示) ---- */
|
|
||||||
.mm-edit__help {
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
align-self: center;
|
|
||||||
|
|
||||||
&:hover .mm-edit__help-pop,
|
|
||||||
&:focus-within .mm-edit__help-pop {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---- 快捷键帮助(右上角 ? 图标,ui Popover hover 展示) ---- */
|
||||||
.mm-edit__help-icon {
|
.mm-edit__help-icon {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -2351,20 +2253,6 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mm-edit__help-pop {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
top: calc(100% + 8px);
|
|
||||||
right: 0;
|
|
||||||
z-index: 50;
|
|
||||||
width: 230px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
border: 1px solid var(--fms-border);
|
|
||||||
border-radius: 8px;
|
|
||||||
background: var(--fms-card);
|
|
||||||
box-shadow: 0 6px 20px rgba(30, 45, 64, 0.14);
|
|
||||||
}
|
|
||||||
|
|
||||||
.mm-edit__help-title {
|
.mm-edit__help-title {
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
color: var(--fms-text);
|
color: var(--fms-text);
|
||||||
@@ -2469,20 +2357,20 @@ onBeforeUnmount(() => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 折叠后的展开按钮:占满折叠列,图标置于顶部 */
|
/* 展开属性面板(覆盖 ui Button 默认尺寸) */
|
||||||
.mm-fdesign__panel-expand {
|
.mm-fdesign__panel-expand.button {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
border: none;
|
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: color-mix(in srgb, var(--fms-text-secondary) 70%, var(--fms-text));
|
color: color-mix(in srgb, var(--fms-text-secondary) 70%, var(--fms-text));
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover:not(:disabled) {
|
||||||
|
background: transparent;
|
||||||
color: var(--fms-primary);
|
color: var(--fms-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2522,49 +2410,33 @@ onBeforeUnmount(() => {
|
|||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 面板头部折叠按钮 */
|
/* 折叠属性面板(覆盖 ui Button 默认尺寸) */
|
||||||
.mm-fdesign__collapse {
|
.mm-fdesign__collapse.button {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
|
min-height: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: color-mix(in srgb, var(--fms-text-secondary) 70%, var(--fms-text));
|
color: color-mix(in srgb, var(--fms-text-secondary) 70%, var(--fms-text));
|
||||||
cursor: pointer;
|
transform: none;
|
||||||
transition:
|
|
||||||
background 0.15s,
|
|
||||||
color 0.15s;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover:not(:disabled) {
|
||||||
background: var(--fms-secondary);
|
background: var(--fms-secondary);
|
||||||
color: var(--fms-text);
|
color: var(--fms-text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mm-fdesign__lib-search {
|
/* 搜索框:压缩 ui Input 高度(覆盖默认 --fms-control-height) */
|
||||||
width: 100%;
|
.mm-fdesign__lib-search.input-wrapper {
|
||||||
height: 26px;
|
height: 26px;
|
||||||
|
min-height: 0;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
border: 1px solid var(--fms-border);
|
|
||||||
border-radius: 4px;
|
|
||||||
color: var(--fms-text);
|
|
||||||
background: var(--fms-card);
|
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
outline: none;
|
|
||||||
|
|
||||||
&::placeholder {
|
|
||||||
color: var(--fms-text-placeholder, #9ca3af);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
border-color: var(--fms-primary);
|
|
||||||
box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--fms-primary) 25%, transparent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mm-fdesign__lib-group {
|
.mm-fdesign__lib-group {
|
||||||
@@ -2709,18 +2581,17 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
/* 分组名编辑输入框 + 确认/取消:宽度自适应(填满标题栏剩余空间),
|
/* 分组名编辑输入框 + 确认/取消:宽度自适应(填满标题栏剩余空间),
|
||||||
* 短标题(如"基础")不会撑出大片空白,长标题自动延伸 */
|
* 短标题(如"基础")不会撑出大片空白,长标题自动延伸 */
|
||||||
.mm-fdesign__section-edit {
|
.mm-fdesign__section-edit.input-wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
min-height: 0;
|
||||||
padding: 0 6px;
|
padding: 0 6px;
|
||||||
border: 1px solid var(--fms-primary);
|
border: 1px solid var(--fms-primary);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: var(--fms-card);
|
background: var(--fms-card);
|
||||||
color: var(--fms-text);
|
color: var(--fms-text);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-family: inherit;
|
|
||||||
outline: none;
|
|
||||||
box-shadow: 0 0 0 2px color-mix(in srgb, var(--fms-primary) 12%, transparent);
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--fms-primary) 12%, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2731,25 +2602,25 @@ onBeforeUnmount(() => {
|
|||||||
flex: none;
|
flex: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mm-fdesign__section-edit-btn {
|
.mm-fdesign__section-edit-btn.button {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 22px;
|
width: 22px;
|
||||||
height: 22px;
|
height: 22px;
|
||||||
|
min-height: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: 1px solid var(--fms-border);
|
border: 1px solid var(--fms-border);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: var(--fms-card);
|
background: var(--fms-card);
|
||||||
color: var(--fms-text-secondary);
|
color: var(--fms-text-secondary);
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover:not(:disabled) {
|
||||||
border-color: var(--fms-primary);
|
border-color: var(--fms-primary);
|
||||||
color: var(--fms-primary);
|
color: var(--fms-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child:hover {
|
&:last-child:hover:not(:disabled) {
|
||||||
border-color: #d95757;
|
border-color: #d95757;
|
||||||
color: #d95757;
|
color: #d95757;
|
||||||
}
|
}
|
||||||
@@ -2981,30 +2852,30 @@ textarea.mm-fdesign__ctrl {
|
|||||||
pointer-events: none; /* 纯预览,点击穿透到卡片 */
|
pointer-events: none; /* 纯预览,点击穿透到卡片 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 字段删除按钮:与必填/显示图标同款行内小图标,推至最右 */
|
/* 字段删除按钮:与必填/显示图标同款行内小图标,推至最右(覆盖 ui Button 默认尺寸) */
|
||||||
.mm-fdesign__tool-btn {
|
.mm-fdesign__tool-btn.button {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
|
min-height: 0;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: color-mix(in srgb, var(--fms-primary) 5%, transparent);
|
background: color-mix(in srgb, var(--fms-primary) 5%, transparent);
|
||||||
color: var(--fms-text-disabled, #9ca3af);
|
color: var(--fms-text-disabled, #9ca3af);
|
||||||
cursor: pointer;
|
|
||||||
transition:
|
transition:
|
||||||
background 0.15s,
|
background 0.15s,
|
||||||
color 0.15s;
|
color 0.15s;
|
||||||
|
|
||||||
&:hover {
|
&:hover:not(:disabled) {
|
||||||
background: color-mix(in srgb, var(--fms-primary) 16%, transparent);
|
background: color-mix(in srgb, var(--fms-primary) 16%, transparent);
|
||||||
color: var(--fms-text);
|
color: var(--fms-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-danger:hover {
|
&.is-danger:hover:not(:disabled) {
|
||||||
color: #d95757;
|
color: #d95757;
|
||||||
background: color-mix(in srgb, #d95757 12%, transparent);
|
background: color-mix(in srgb, #d95757 12%, transparent);
|
||||||
}
|
}
|
||||||
@@ -3113,37 +2984,32 @@ textarea.mm-fdesign__ctrl {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
input[type='number'] {
|
/* 数字输入:压缩 ui Input 高度(覆盖默认 --fms-control-height) */
|
||||||
flex: none;
|
.mm-fdesign__span-input.input-wrapper {
|
||||||
width: 48px;
|
flex: none;
|
||||||
height: 26px;
|
width: 48px;
|
||||||
padding: 0 4px;
|
height: 26px;
|
||||||
border: 1px solid var(--fms-border);
|
min-height: 0;
|
||||||
border-radius: 4px;
|
padding: 0 4px;
|
||||||
background: var(--fms-card);
|
font-size: 11px;
|
||||||
color: var(--fms-text);
|
|
||||||
font-size: 11px;
|
:deep(.input) {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
outline: none;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
border-color: var(--fms-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 栅格宽度:去掉下拉后数字输入框即主控件,填充剩余宽度(列宽控件仍用下拉,不受影响) */
|
/* 栅格宽度:无下拉时数字输入框即主控件,填充剩余宽度(文本域高度仍用下拉,不受影响) */
|
||||||
.mm-fdesign__span-control input#mm-fdesign-colspan {
|
.mm-fdesign__span-control > .mm-fdesign__span-input.input-wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
text-align: left;
|
|
||||||
|
:deep(.input) {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mm-fdesign__prop-static {
|
.mm-fdesign__prop-static {
|
||||||
@@ -3158,25 +3024,12 @@ textarea.mm-fdesign__ctrl {
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mm-fdesign__prop-input {
|
/* 属性面板常规输入:压缩 ui Input 高度 */
|
||||||
width: 100%;
|
.mm-fdesign__prop-input.input-wrapper {
|
||||||
height: 26px;
|
height: 26px;
|
||||||
|
min-height: 0;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
border: 1px solid var(--fms-border);
|
|
||||||
border-radius: 4px;
|
|
||||||
background: var(--fms-card);
|
|
||||||
color: var(--fms-text);
|
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
outline: none;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
border-color: var(--fms-primary);
|
|
||||||
box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--fms-primary) 20%, transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mm-fdesign__toggles {
|
.mm-fdesign__toggles {
|
||||||
@@ -3192,40 +3045,6 @@ textarea.mm-fdesign__ctrl {
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mm-fdesign__toggle {
|
|
||||||
width: 30px;
|
|
||||||
height: 16px;
|
|
||||||
padding: 2px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 999px;
|
|
||||||
background: #bdc7d2;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.16s ease;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #fff;
|
|
||||||
transition: transform 0.16s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-on {
|
|
||||||
background: var(--fms-primary);
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
transform: translateX(14px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mm-fdesign__delete {
|
.mm-fdesign__delete {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -3496,25 +3315,25 @@ textarea.mm-fdesign__ctrl {
|
|||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- 分组设置按钮(齿轮):打开分组设置弹窗 ---- */
|
/* ---- 分组设置按钮(齿轮):打开分组设置弹窗(覆盖 ui Button 默认尺寸) ---- */
|
||||||
.mm-fdesign__section-btn {
|
.mm-fdesign__section-btn.button {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
|
min-height: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--fms-text-placeholder, #9ca3af);
|
color: var(--fms-text-placeholder, #9ca3af);
|
||||||
cursor: pointer;
|
|
||||||
transition:
|
transition:
|
||||||
background 0.15s,
|
background 0.15s,
|
||||||
color 0.15s,
|
color 0.15s,
|
||||||
border-color 0.15s;
|
border-color 0.15s;
|
||||||
|
|
||||||
&:hover {
|
&:hover:not(:disabled) {
|
||||||
background: var(--fms-secondary-hover, #f1f5f9);
|
background: var(--fms-secondary-hover, #f1f5f9);
|
||||||
color: var(--fms-text);
|
color: var(--fms-text);
|
||||||
border-color: var(--fms-border);
|
border-color: var(--fms-border);
|
||||||
|
|||||||
Reference in new issue
Block a user