forked from opentiny/tiny-engine
feat(setting-stylePanel): 样式面板编辑全局样式新UI与交互 (#238)
* feat(setting-stylePanel): 样式面板编辑全局样式新UI与交互 * feat(setting-stylePanel): 样式面板编辑全局样式新UI与交互 * feat(setting-stylePanel): 样式面板编辑全局样式新UI与交互-细节优化 * feat(setting-stylePanel): 样式面板编辑全局样式新UI与交互-细节优化 * fix(settingPanel-style): 样式面板新交互细节调整 * fix(setting-stylePanel): 修复样式选择器颜色不对的 bug * fix(setting-stylePanel): 样式选择器间距调整 * fix(setting-stylePanel): 调整样式选择器距离顶部距离与下拉列表滚动条颜色 * feat(setting-style): add help link button * fix(setting-style): delete empty row by code review
This commit is contained in:
parent
dec9334eb8
commit
28ee851b2a
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<div class="editor-wrap">
|
||||
<slot>
|
||||
<slot :open="open">
|
||||
<div v-if="buttonShowContent" :class="['full-width', { 'empty-color': value === '' }]" @click="open">
|
||||
<span>{{ value === '' ? buttonLabel : value?.slice(0, 30) }}</span>
|
||||
<svg-icon class="edit-icon" name="flow-edit"></svg-icon>
|
||||
<span class="text-content text-ellipsis-multiple">{{ value === '' ? buttonLabel : value }}</span>
|
||||
<svg-icon class="edit-icon" name="edit"></svg-icon>
|
||||
</div>
|
||||
<tiny-button v-else class="edit-btn" @click="open">
|
||||
{{ buttonLabel }}
|
||||
|
@ -15,6 +15,7 @@
|
|||
width="50vw"
|
||||
class="meta-code-editor-dialog-box"
|
||||
append-to-body
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div class="source-code">
|
||||
<div v-if="editorTipsTitle" class="header-tips-container">
|
||||
|
@ -45,7 +46,13 @@
|
|||
</div>
|
||||
<template #footer>
|
||||
<div class="btn-box">
|
||||
<tiny-button plain type="danger" v-if="language === 'json' && showFormatBtn" @click="formatCode">
|
||||
<tiny-button
|
||||
v-if="language === 'json' && showFormatBtn"
|
||||
class="format-btn"
|
||||
plain
|
||||
type="danger"
|
||||
@click="formatCode"
|
||||
>
|
||||
{{ $t('common.format') }}
|
||||
</tiny-button>
|
||||
<div>
|
||||
|
@ -269,20 +276,32 @@ export default {
|
|||
}
|
||||
.btn-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-end;
|
||||
&:has(.format-btn) {
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
.full-width {
|
||||
border: 1px solid #adb0b8;
|
||||
border-radius: 6px;
|
||||
padding: 4px 8px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
padding: 4px 8px;
|
||||
border: 1px solid var(--ti-lowcode-meta-codeEditor-border-color);
|
||||
border-radius: 6px;
|
||||
&:hover {
|
||||
border-color: var(--ti-lowcode-meta-codeEditor-border-hover-color);
|
||||
}
|
||||
.text-content {
|
||||
--ellipsis-line: 1;
|
||||
}
|
||||
&.empty-color {
|
||||
color: var(--ti-lowcode-common-text-desc-color);
|
||||
}
|
||||
.edit-icon {
|
||||
margin-left: 4px;
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
color: var(--ti-lowcode-common-text-main-color);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ const helpState = {
|
|||
datasource: 11,
|
||||
i18n: 12,
|
||||
page: 2,
|
||||
script: 8
|
||||
script: 8,
|
||||
stylePanel: 6
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" xml:space="preserve" isSvg="true">
|
||||
<path d="M14 7c0 3.87-3.13 7-7 7s-7-3.13-7-7 3.13-7 7-7 7 3.13 7 7z" style="fill-rule: evenodd; clip-rule: evenodd;"></path>
|
||||
<path d="M9.96 9.29c.09.09.14.21.14.34 0 .13-.05.25-.14.33a.47.47 0 0 1-.67 0L7 7.67 4.71 9.96c-.18.18-.49.18-.67 0a.483.483 0 0 1 0-.67L6.33 7 4.04 4.71c-.09-.09-.14-.21-.14-.34s.05-.25.14-.34c.18-.18.49-.18.67 0L7 6.33l2.29-2.29c.19-.18.49-.18.67 0 .09.09.14.21.14.34s-.05.25-.14.34L7.67 7l2.29 2.29z" style="fill: rgb(255, 255, 255);"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 576 B |
|
@ -47,10 +47,6 @@ export default {
|
|||
padding-top: 20px;
|
||||
background-color: var(--ti-lowcode-setting-panel-bg-color);
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tiny-tabs {
|
||||
height: 100%;
|
||||
}
|
||||
|
|
|
@ -1,24 +1,17 @@
|
|||
<template>
|
||||
<div class="style-editor">
|
||||
<meta-code-editor
|
||||
:modelValue="state.cssContent"
|
||||
title="Css 编辑"
|
||||
button-text="编辑全局样式"
|
||||
language="css"
|
||||
single
|
||||
@save="save(CSS_TYPE.Css, $event)"
|
||||
/>
|
||||
<div class="line-style">
|
||||
<span class="line-text"> 行内样式 </span>
|
||||
<div class="inline-style">
|
||||
<meta-code-editor
|
||||
v-if="state.lineStyleDisable"
|
||||
:buttonShowContent="true"
|
||||
:modelValue="state.styleContent"
|
||||
title="编辑行内样式"
|
||||
:button-text="state.inlineBtnText"
|
||||
language="css"
|
||||
single
|
||||
@save="save(CSS_TYPE.Style, $event)"
|
||||
@save="save"
|
||||
/>
|
||||
<div v-if="!state.lineStyleDisable">
|
||||
<tiny-input v-model="state.propertiesList" class="inline-bind-style"> </tiny-input>
|
||||
|
@ -75,7 +68,7 @@
|
|||
import { ref, watch } from 'vue'
|
||||
import { Collapse, CollapseItem, Input } from '@opentiny/vue'
|
||||
import { useHistory, useCanvas, useProperties } from '@opentiny/tiny-engine-controller'
|
||||
import { setPageCss, getSchema as getCanvasPageSchema } from '@opentiny/tiny-engine-canvas'
|
||||
import { getSchema as getCanvasPageSchema, updateRect } from '@opentiny/tiny-engine-canvas'
|
||||
import { MetaCodeEditor, MetaBindVariable } from '@opentiny/tiny-engine-common'
|
||||
import { formatString } from '@opentiny/tiny-engine-common/js/ast'
|
||||
import {
|
||||
|
@ -125,43 +118,33 @@ export default {
|
|||
'borders',
|
||||
'effects'
|
||||
])
|
||||
const { getCurrentSchema, getPageSchema } = useCanvas()
|
||||
const { getCurrentSchema } = useCanvas()
|
||||
// 获取当前节点 style 对象
|
||||
const { state, updateStyle } = useStyle() // updateStyle
|
||||
const { addHistory } = useHistory()
|
||||
const { getSchema } = useProperties()
|
||||
|
||||
// 打开编辑器
|
||||
|
||||
// 保存编辑器内容,并回写到 schema
|
||||
const save = (type, { content }) => {
|
||||
if (type === CSS_TYPE.Style) {
|
||||
const pageSchema = getCanvasPageSchema()
|
||||
const schema = getSchema() || pageSchema
|
||||
const styleString = formatString(styleStrRemoveRoot(content), 'css')
|
||||
const currentSchema = getCurrentSchema() || pageSchema
|
||||
const save = ({ content }) => {
|
||||
const pageSchema = getCanvasPageSchema()
|
||||
const schema = getSchema() || pageSchema
|
||||
const styleString = formatString(styleStrRemoveRoot(content), 'css')
|
||||
const currentSchema = getCurrentSchema() || pageSchema
|
||||
|
||||
state.styleContent = content
|
||||
schema.props = schema.props || {}
|
||||
schema.props.style = styleString
|
||||
state.styleContent = content
|
||||
schema.props = schema.props || {}
|
||||
schema.props.style = styleString
|
||||
|
||||
currentSchema.props = currentSchema.props || {}
|
||||
currentSchema.props = currentSchema.props || {}
|
||||
|
||||
if (styleString) {
|
||||
currentSchema.props.style = styleString
|
||||
} else {
|
||||
delete currentSchema.props.style
|
||||
}
|
||||
|
||||
addHistory()
|
||||
} else if (type === CSS_TYPE.Css) {
|
||||
const cssString = formatString(content.replace(/"/g, "'"), 'css')
|
||||
getPageSchema().css = cssString
|
||||
getCanvasPageSchema().css = cssString
|
||||
setPageCss(cssString)
|
||||
state.schemaUpdateKey++
|
||||
addHistory()
|
||||
if (styleString) {
|
||||
currentSchema.props.style = styleString
|
||||
} else {
|
||||
delete currentSchema.props.style
|
||||
}
|
||||
|
||||
addHistory()
|
||||
updateRect()
|
||||
}
|
||||
|
||||
const setConfig = (value) => {
|
||||
|
@ -181,6 +164,8 @@ export default {
|
|||
state.lineStyleDisable = true
|
||||
addHistory()
|
||||
}
|
||||
|
||||
updateRect()
|
||||
}
|
||||
|
||||
watch(
|
||||
|
@ -218,21 +203,22 @@ export default {
|
|||
<style lang="less" scoped>
|
||||
.style-editor {
|
||||
justify-content: space-around;
|
||||
padding: 8px 16px 12px;
|
||||
padding: 8px 16px 0;
|
||||
column-gap: 8px;
|
||||
.line-style {
|
||||
display: block;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 8px;
|
||||
color: var(--ti-lowcode-setting-style-font-color);
|
||||
font-size: 12px;
|
||||
.line-text {
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
color: var(--ti-lowcode-setting-style-title-color);
|
||||
}
|
||||
}
|
||||
.inline-style {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
:deep(.editor-wrap) {
|
||||
display: flex;
|
||||
.tiny-button {
|
||||
|
@ -257,8 +243,5 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
:deep(.svg-icon) {
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,113 +1,113 @@
|
|||
<template>
|
||||
<div class="className-container">
|
||||
<h6 class="title">样式选择器</h6>
|
||||
<h6 class="title">
|
||||
<span>全局样式</span>
|
||||
<link-button :href="docsUrl" class="help-link"></link-button>
|
||||
</h6>
|
||||
<div class="selector-container">
|
||||
<div class="className-selector-wrap">
|
||||
<div
|
||||
:class="['className-selector-container', { 'has-error': classNameState.selectorHasError }]"
|
||||
@click="handleFocusInput"
|
||||
>
|
||||
<div v-if="classNameState.curSelector || classNameState.curSelectorIsEditing" class="current-selector">
|
||||
<div class="current-selector-label">
|
||||
<span
|
||||
ref="selectorTextRef"
|
||||
:contenteditable="classNameState.curSelectorIsEditing"
|
||||
:class="['selector-label-text', { 'text-editing': classNameState.curSelectorIsEditing }]"
|
||||
:key="classNameState.curSelectorIsEditing"
|
||||
@click.stop="handleEditCurSelector"
|
||||
@input="handleCurSelectorChange"
|
||||
@blur="handleCompleteEditCurSelector"
|
||||
@keyup.enter="handleCompleteEditCurSelector"
|
||||
@keyup.esc="handleCompleteEditCurSelector"
|
||||
>
|
||||
{{ classNameState.curSelector }}
|
||||
</span>
|
||||
<div v-if="!classNameState.curSelectorIsEditing && classNameState.curSelectorEditable" class="edit-wrap">
|
||||
<svg-icon name="edit" title="编辑" class="edit-btn" @click.stop="handleEditCurSelector"></svg-icon>
|
||||
<tiny-popover
|
||||
v-model="classNameState.showDelConfirm"
|
||||
trigger="manual"
|
||||
class="del-selector-popover"
|
||||
popper-class="del-selector-popper-wrapper"
|
||||
<meta-code-editor
|
||||
:modelValue="state.cssContent"
|
||||
title="Css 编辑"
|
||||
language="css"
|
||||
v-slot="scope"
|
||||
single
|
||||
@save="save"
|
||||
>
|
||||
<div class="edit-global-css" title="编辑全局样式" @click="scope.open">
|
||||
<svg-icon name="edit"></svg-icon>
|
||||
</div>
|
||||
</meta-code-editor>
|
||||
<div class="selector-right-container">
|
||||
<div class="selector-right-container-wrap">
|
||||
<div
|
||||
:class="['className-selector-container', { 'has-error': classNameState.selectorHasError }]"
|
||||
@click="handleFocusInput"
|
||||
>
|
||||
<div v-if="classNameState.curSelector || classNameState.curSelectorIsEditing" class="current-selector">
|
||||
<div class="current-selector-label">
|
||||
<span
|
||||
ref="selectorTextRef"
|
||||
:contenteditable="classNameState.curSelectorIsEditing"
|
||||
:class="['selector-label-text', { 'text-editing': classNameState.curSelectorIsEditing }]"
|
||||
:key="classNameState.curSelectorIsEditing"
|
||||
:title="classNameState.curSelector"
|
||||
@click.stop="handleEditCurSelector"
|
||||
@input="handleCurSelectorChange"
|
||||
@blur="handleCompleteEditCurSelector"
|
||||
@keyup.enter="handleCompleteEditCurSelector"
|
||||
@keyup.esc="handleCompleteEditCurSelector"
|
||||
>
|
||||
<div class="popper-confirm" @mousedown.stop="">
|
||||
<div class="popper-confirm-header">
|
||||
<svg-icon class="icon" name="warning"></svg-icon>
|
||||
<span class="title">您确定删除该选择器吗?</span>
|
||||
</div>
|
||||
<div class="popper-confirm-footer">
|
||||
<tiny-button class="confirm-btn" size="small" type="primary" @click="handleDelSelector">
|
||||
确定
|
||||
</tiny-button>
|
||||
<tiny-button size="small" class="cancel-btn" @click="handleTriggerDelConfirm(false)">
|
||||
取消
|
||||
</tiny-button>
|
||||
</div>
|
||||
</div>
|
||||
<template #reference>
|
||||
<svg-icon
|
||||
name="delete"
|
||||
title="删除"
|
||||
class="delete-btn"
|
||||
@click.stop="handleTriggerDelConfirm(true)"
|
||||
></svg-icon>
|
||||
</template>
|
||||
</tiny-popover>
|
||||
{{ classNameState.curSelector }}
|
||||
</span>
|
||||
<div
|
||||
v-if="!classNameState.curSelectorIsEditing && classNameState.curSelectorEditable"
|
||||
class="edit-wrap"
|
||||
>
|
||||
<svg-icon name="edit" title="编辑" class="edit-btn" @click.stop="handleEditCurSelector"></svg-icon>
|
||||
<svg-icon name="close" title="删除" class="delete-btn" @click.stop="handleDelSelector"></svg-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span v-else class="empty-tips">请选择或创建类名</span>
|
||||
<input
|
||||
ref="newSelectorInputRef"
|
||||
type="text"
|
||||
v-model="classNameState.newSelector"
|
||||
class="selector-input"
|
||||
@change="handleInputChange"
|
||||
@blur="handleCreateNewClass"
|
||||
@keyup.enter="handleCreateNewClass"
|
||||
@keydown.delete="handleDeleteCurSelector"
|
||||
/>
|
||||
</div>
|
||||
<span v-else class="empty-tips">请选择或创建类名</span>
|
||||
<input
|
||||
ref="newSelectorInputRef"
|
||||
type="text"
|
||||
v-model="classNameState.newSelector"
|
||||
class="selector-input"
|
||||
@change="handleInputChange"
|
||||
@blur="handleCreateNewClass"
|
||||
@keyup.enter="handleCreateNewClass"
|
||||
/>
|
||||
<div v-if="classNameState.showDropdownList" class="selector-drop-down-list">
|
||||
<span class="selector-dropdown-list-tips">输入并回车创建新选择器</span>
|
||||
<span v-if="currentSelectorList.length" class="selector-dropdown-list-tips">选择已有选择器编辑</span>
|
||||
<ul class="exist-class-list">
|
||||
<li
|
||||
v-for="item in currentSelectorList"
|
||||
:key="item"
|
||||
:title="item"
|
||||
class="exist-class-item"
|
||||
@mousedown="handleSelectExistingClass(item)"
|
||||
>
|
||||
<span>{{ item }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<span v-if="state.selectors.length" class="selector-dropdown-list-tips add-global-class-tips">
|
||||
添加全局类到当前组件并编辑
|
||||
</span>
|
||||
<ul class="exist-class-list">
|
||||
<li
|
||||
v-for="item in state.selectors"
|
||||
:key="item"
|
||||
:title="item"
|
||||
class="exist-class-item"
|
||||
@mousedown="handleSelectExistingClass(item)"
|
||||
>
|
||||
<span>{{ item }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<tiny-select v-model="state.className.mouseState" :options="stateOptions" class="state-selector">
|
||||
</tiny-select>
|
||||
</div>
|
||||
<div v-if="classNameState.selectorHasError" class="error-tips">
|
||||
<svg-icon name="error"></svg-icon>
|
||||
<span class="error-tips-text">{{ classNameState.selectorHasError }}</span>
|
||||
</div>
|
||||
<div v-if="classNameState.showDropdownList" class="selector-drop-down-list lowcode-scrollbar-thin">
|
||||
<span class="selector-dropdown-list-tips">输入并回车创建新选择器</span>
|
||||
<span v-if="currentSelectorList.length" class="selector-dropdown-list-tips">选择已有选择器编辑</span>
|
||||
<ul class="exist-class-list">
|
||||
<li
|
||||
v-for="item in currentSelectorList"
|
||||
:key="item"
|
||||
:title="item"
|
||||
class="exist-class-item"
|
||||
@mousedown="handleSelectExistingClass(item)"
|
||||
>
|
||||
<span>{{ item }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<span v-if="state.selectors.length" class="selector-dropdown-list-tips add-global-class-tips">
|
||||
添加全局类到当前组件并编辑
|
||||
</span>
|
||||
<ul class="exist-class-list">
|
||||
<li
|
||||
v-for="item in state.selectors"
|
||||
:key="item"
|
||||
:title="item"
|
||||
class="exist-class-item"
|
||||
@mousedown="handleSelectExistingClass(item)"
|
||||
>
|
||||
<span>{{ item }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div v-if="classNameState.selectorHasError" class="error-tips">{{ classNameState.selectorHasError }}</div>
|
||||
</div>
|
||||
<tiny-select v-model="state.className.mouseState" :options="stateOptions" class="state-selector"> </tiny-select>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, reactive, ref, nextTick, watch, watchEffect } from 'vue'
|
||||
import { Select as TinySelect, Popover as TinyPopover, Button as TinyButton } from '@opentiny/vue'
|
||||
import { getSchema as getCanvasPageSchema } from '@opentiny/tiny-engine-canvas'
|
||||
import { useProperties } from '@opentiny/tiny-engine-controller'
|
||||
import { Select as TinySelect } from '@opentiny/vue'
|
||||
import { setPageCss, getSchema as getCanvasPageSchema, updateRect } from '@opentiny/tiny-engine-canvas'
|
||||
import { useProperties, useCanvas, useHistory, useHelp } from '@opentiny/tiny-engine-controller'
|
||||
import { MetaCodeEditor, LinkButton } from '@opentiny/tiny-engine-common'
|
||||
import { formatString } from '@opentiny/tiny-engine-common/js/ast'
|
||||
import useStyle, { updateGlobalStyleStr } from '../../js/useStyle'
|
||||
import { stringify, getSelectorArr } from '../../js/parser'
|
||||
|
||||
|
@ -131,6 +131,8 @@ const OPTION_TYPE = {
|
|||
EDIT: 'edit'
|
||||
}
|
||||
|
||||
const docsUrl = useHelp().getDocsUrl('stylePanel')
|
||||
|
||||
const classNameState = reactive({
|
||||
curSelector: '',
|
||||
curSelectorEditable: false,
|
||||
|
@ -182,7 +184,14 @@ const setSelectorProps = (type, value) => {
|
|||
// 编辑 className 新增、删除、或修改
|
||||
const editClassName = (curClassName, optionType = OPTION_TYPE.ADD, oldSelector = '') => {
|
||||
const schema = getSchema() || getCanvasPageSchema()
|
||||
const type = curClassName.startsWith('.') ? SELECTOR_TYPE.CLASS_NAME : SELECTOR_TYPE.ID
|
||||
let type = ''
|
||||
|
||||
if (curClassName.startsWith('.')) {
|
||||
type = SELECTOR_TYPE.CLASS_NAME
|
||||
} else if (curClassName.startsWith('#')) {
|
||||
type = SELECTOR_TYPE.ID
|
||||
}
|
||||
|
||||
const classNames = schema.props.className || ''
|
||||
const ids = schema.props.id || ''
|
||||
const typeMap = {
|
||||
|
@ -396,25 +405,12 @@ const handleCompleteEditCurSelector = () => {
|
|||
updateGlobalStyleStr(newStyleStr)
|
||||
}
|
||||
|
||||
const listener = () => {
|
||||
classNameState.showDelConfirm = false
|
||||
}
|
||||
|
||||
// 删除确认弹窗
|
||||
const handleTriggerDelConfirm = (visible) => {
|
||||
classNameState.showDelConfirm = visible
|
||||
|
||||
if (visible) {
|
||||
window.addEventListener('click', listener)
|
||||
} else {
|
||||
window.removeEventListener('click', listener)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelSelector = () => {
|
||||
// 删除选择器,仅从当前选中组件中删除类名, 不删除全局 css 中的 css 类名和样式
|
||||
// 后期需要可以拿到全局组件的类名,如果只有当前组件使用该类名,从全局样式中删除之
|
||||
editClassName(classNameState.curSelector, OPTION_TYPE.REMOVE)
|
||||
state.className.classNameList = ''
|
||||
state.className.mouseState = ''
|
||||
}
|
||||
|
||||
const handleFocusInput = () => {
|
||||
|
@ -436,46 +432,104 @@ const handleCurSelectorChange = (event) => {
|
|||
watchEffect(() => {
|
||||
selectorValidator(classNameState.newSelector)
|
||||
})
|
||||
|
||||
const save = ({ content }) => {
|
||||
const cssString = formatString(content.replace(/"/g, "'"), 'css')
|
||||
const { getPageSchema } = useCanvas()
|
||||
const { addHistory } = useHistory()
|
||||
getPageSchema().css = cssString
|
||||
getCanvasPageSchema().css = cssString
|
||||
setPageCss(cssString)
|
||||
state.schemaUpdateKey++
|
||||
|
||||
addHistory()
|
||||
updateRect()
|
||||
}
|
||||
|
||||
// 监听回车删除键,如果当前输入为空,则解绑当前选择器
|
||||
const handleDeleteCurSelector = () => {
|
||||
// 当前新建的选择器不为空,则在编辑当前选择器
|
||||
if (classNameState.newSelector) {
|
||||
return
|
||||
}
|
||||
|
||||
// 在编辑当前选择器则不做更改
|
||||
if (classNameState.curSelectorIsEditing) {
|
||||
return
|
||||
}
|
||||
|
||||
// 解绑当前选择器
|
||||
handleDelSelector()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.className-container {
|
||||
padding: 10px;
|
||||
::-webkit-scrollbar {
|
||||
display: block;
|
||||
}
|
||||
padding: 16px 16px 8px;
|
||||
}
|
||||
.title {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
color: var(--ti-lowcode-className-selector-title-color);
|
||||
font-weight: normal;
|
||||
.help-link {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.selector-container {
|
||||
display: flex;
|
||||
margin-top: 10px;
|
||||
color: var(--ti-lowcode-className-selector-container-color);
|
||||
|
||||
.selector-right-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
position: relative;
|
||||
margin-left: 8px;
|
||||
}
|
||||
.selector-right-container-wrap {
|
||||
display: flex;
|
||||
}
|
||||
.className-selector-wrap {
|
||||
.error-tips {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: var(--ti-lowcode-className-selector-error-tips-color);
|
||||
}
|
||||
max-width: 180px;
|
||||
min-width: 0;
|
||||
}
|
||||
:deep(.editor-wrap) {
|
||||
width: 30px;
|
||||
}
|
||||
.edit-global-css {
|
||||
display: flex;
|
||||
padding: 7px;
|
||||
border: 1px solid var(--ti-lowcode-className-selector-container-border-color);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.className-selector-container {
|
||||
flex: 7;
|
||||
border: 1px solid var(--ti-lowcode-className-selector-container-border-color);
|
||||
border-radius: 6px;
|
||||
padding: 2px 10px;
|
||||
display: flex;
|
||||
max-width: 180px;
|
||||
row-gap: 2px;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
flex-wrap: wrap;
|
||||
max-width: 180px;
|
||||
min-width: 0;
|
||||
padding: 1px 10px;
|
||||
border: 1px solid var(--ti-lowcode-className-selector-container-border-color);
|
||||
border-radius: 6px;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
font-size: 12px;
|
||||
&:hover {
|
||||
border-color: var(--ti-lowcode-className-selector-container-hover-border-color);
|
||||
}
|
||||
&.has-error {
|
||||
border-color: var(--ti-lowcode-className-selector-container-error-border-color);
|
||||
background-color: var(--ti-lowcode-className-selector-container-error-bg-color);
|
||||
.selector-drop-down-list {
|
||||
top: calc(100% + 30px);
|
||||
}
|
||||
}
|
||||
&:has(.selector-input:focus) {
|
||||
.empty-tips {
|
||||
|
@ -484,7 +538,6 @@ watchEffect(() => {
|
|||
}
|
||||
.empty-tips {
|
||||
position: absolute;
|
||||
font-size: 14px;
|
||||
color: var(--ti-lowcode-className-selector-container-empty-tips-color);
|
||||
z-index: 0;
|
||||
}
|
||||
|
@ -494,10 +547,10 @@ watchEffect(() => {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
background-color: var(--ti-lowcode-className-selector-container-label-bg-color);
|
||||
color: #fff;
|
||||
color: var(--ti-lowcode-className-selector-container-label-color);
|
||||
padding: 1px 4px;
|
||||
border-radius: 2px;
|
||||
line-height: 30px;
|
||||
border-radius: 4px;
|
||||
line-height: 26px;
|
||||
.selector-label-text {
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
|
@ -531,7 +584,7 @@ watchEffect(() => {
|
|||
color: var(--ti-lowcode-className-selector-container-color);
|
||||
min-width: 0;
|
||||
flex: 0 0 0;
|
||||
line-height: 30px;
|
||||
line-height: 28px;
|
||||
z-index: 1;
|
||||
border: none;
|
||||
outline: none;
|
||||
|
@ -542,95 +595,82 @@ watchEffect(() => {
|
|||
padding: 1px 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.selector-drop-down-list {
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
.error-tips {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: var(--ti-lowcode-className-selector-error-tips-color);
|
||||
.error-tips-text {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.selector-drop-down-list {
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-height: 200px;
|
||||
top: calc(100% + 10px);
|
||||
left: 0;
|
||||
padding: 8px 0;
|
||||
background-color: var(--ti-lowcode-className-selector-dropdown-list-bg-color);
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
z-index: 1;
|
||||
flex-direction: column;
|
||||
overflow: scroll;
|
||||
box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.15);
|
||||
|
||||
.selector-dropdown-list-tips {
|
||||
font-size: 12px;
|
||||
padding: 0 10px;
|
||||
line-height: 32px;
|
||||
color: var(--ti-lowcode-className-selector-dropdown-list-tips-color);
|
||||
}
|
||||
|
||||
.selector-dropdown-list-tips + .selector-dropdown-list-tips {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.add-global-class-tips {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.exist-class-item {
|
||||
cursor: pointer;
|
||||
height: 32px;
|
||||
padding: 0 16px;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-height: 200px;
|
||||
top: calc(100% + 10px);
|
||||
left: 0;
|
||||
padding: 8px 0;
|
||||
background-color: var(--ti-lowcode-className-selector-dropdown-list-bg-color);
|
||||
|
||||
border: 1px solid transparent;
|
||||
z-index: 1;
|
||||
flex-direction: column;
|
||||
overflow: scroll;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08);
|
||||
|
||||
.selector-dropdown-list-tips {
|
||||
font-size: 12px;
|
||||
padding: 0 10px;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
> span {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.selector-dropdown-list-tips + .selector-dropdown-list-tips {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.add-global-class-tips {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.exist-class-item {
|
||||
cursor: pointer;
|
||||
height: 32px;
|
||||
padding: 0 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
> span {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
&.active,
|
||||
&:hover {
|
||||
background-color: var(--ti-lowcode-className-selector-dropdown-list-item-active-bg-color);
|
||||
color: var(--ti-lowcode-className-selector-dropdown-list-item-color);
|
||||
}
|
||||
&.active,
|
||||
&:hover {
|
||||
background-color: var(--ti-lowcode-className-selector-dropdown-list-item-active-bg-color);
|
||||
color: var(--ti-lowcode-className-selector-dropdown-list-item-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.state-selector {
|
||||
flex: 4;
|
||||
flex-shrink: 0;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
color: var(--ti-lowcode-className-selector-title-color);
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.tiny-popover.tiny-popper.del-selector-popper-wrapper {
|
||||
width: 220px;
|
||||
height: 108px;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--ti-lowcode-className-selector-del-popover-bg-color);
|
||||
padding: 6px;
|
||||
|
||||
.popper-confirm {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.popper-confirm-header {
|
||||
font-size: 12px;
|
||||
color: var(--ti-lowcode-className-selector-del-popover-title-color);
|
||||
.icon {
|
||||
color: var(--ti-lowcode-warning-color);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
min-width: 84px;
|
||||
border: 1px solid var(--ti-lowcode-className-selector-container-border-color);
|
||||
border-radius: 6px;
|
||||
border-left: none;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
:deep(input) {
|
||||
padding-right: 30px;
|
||||
border: none;
|
||||
font-size: 12px;
|
||||
}
|
||||
.title {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
.popper-confirm-footer {
|
||||
text-align: center;
|
||||
margin-top: 22px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -166,7 +166,7 @@ watch(
|
|||
state.style = {}
|
||||
}
|
||||
|
||||
state.styleContent = `:root {\n ${schema?.props?.style || ''}\n}`
|
||||
state.styleContent = formatString(`:root {\n ${schema?.props?.style || ''}\n}`, 'css')
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
|
|
|
@ -4,4 +4,5 @@
|
|||
--ti-lowcode-setting-style-input-font-color: var(--ti-lowcode-base-gray-0);
|
||||
--ti-lowcode-setting-style-btn-font-color: var(--ti-lowcode-base-gray-40);
|
||||
--ti-lowcode-setting-style-btn-border-color: var(--ti-lowcode-base-blue-6);
|
||||
--ti-lowcode-setting-style-title-color: var(--ti-lowcode-base-text-color);
|
||||
}
|
||||
|
|
|
@ -30,12 +30,14 @@
|
|||
--ti-lowcode-className-selector-container-border-color: var(--ti-lowcode-base-gray-40);
|
||||
--ti-lowcode-className-selector-container-hover-border-color: var(--ti-lowcode-base-primary-color-2);
|
||||
--ti-lowcode-className-selector-container-empty-tips-color: var(--ti-lowcode-base-text-color-1);
|
||||
--ti-lowcode-className-selector-container-label-bg-color: var(--ti-lowcode-base-blue-6);
|
||||
--ti-lowcode-className-selector-container-option-btn-color: var(--ti-lowcode-base-gray-0);
|
||||
--ti-lowcode-className-selector-container-label-bg-color: rgba(20, 118, 255, 0.1);
|
||||
--ti-lowcode-className-selector-container-label-color: var(--ti-lowcode-base-blue-6);
|
||||
--ti-lowcode-className-selector-container-option-btn-color: var(--ti-lowcode-base-blue-6);
|
||||
--ti-lowcode-className-selector-dropdown-list-bg-color: #202020;
|
||||
--ti-lowcode-className-selector-dropdown-list-item-color: var(--ti-lowcode-base-text-color);
|
||||
--ti-lowcode-className-selector-dropdown-list-item-active-bg-color: var(--ti-lowcode-base-bg-2);
|
||||
--ti-lowcode-className-selector-title-color: var(--ti-lowcode-base-text-color);
|
||||
--ti-lowcode-className-selector-dropdown-list-tips-color: var(--ti-lowcode-base-text-color-3);
|
||||
}
|
||||
|
||||
:root {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--ti-lowcode-base-gray-0: #fff;
|
||||
--ti-lowcode-base-gray-5: #fafafa;
|
||||
--ti-lowcode-base-gray-10: #f5f5f5;
|
||||
--ti-lowcode-base-gray-20: #ebebeb;
|
||||
--ti-lowcode-base-gray-20: #f0f0f0;
|
||||
--ti-lowcode-base-gray-30: #dbdbdb;
|
||||
--ti-lowcode-base-gray-40: #c2c2c2;
|
||||
--ti-lowcode-base-gray-50: #808080;
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
|
||||
// MetaCodeEditor
|
||||
--ti-lowcode-meta-codeEditor-color: var(--ti-lowcode-base-text-color);
|
||||
--ti-lowcode-meta-codeEditor-border-color: var(--ti-lowcode-base-secondary-button-border-color);
|
||||
--ti-lowcode-meta-codeEditor-hover-color: var(--ti-lowcode-base-text-color);
|
||||
--ti-lowcode-meta-codeEditor-border-hover-color: var(--ti-lowcode-base-secondary-button-border-hover-color);
|
||||
--ti-lowcode-meta-codeEditor-border-color: var(--ti-lowcode-base-default-button-border-color);
|
||||
--ti-lowcode-meta-codeEditor-border-hover-color: var(--ti-lowcode-base-default-button-border-hover-color);
|
||||
}
|
||||
|
||||
// config-item label popover tips
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
:root {
|
||||
--ti-lowcode-setting-style-input-bg: var(--ti-lowcode-base-blue-6);
|
||||
--ti-lowcode-setting-style-font-color: var(--ti-lowcode-base-gray-60);
|
||||
--ti-lowcode-setting-style-font-color: var(--ti-lowcode-base-text-color);
|
||||
--ti-lowcode-setting-style-input-font-color: var(--ti-lowcode-base-gray-0);
|
||||
--ti-lowcode-setting-style-btn-font-color: var(--ti-lowcode-base-gray-50);
|
||||
--ti-lowcode-setting-style-btn-border-color: var(--ti-lowcode-base-gray-90);
|
||||
--ti-lowcode-setting-style-title-color: var(--ti-lowcode-base-text-color);
|
||||
}
|
||||
|
|
|
@ -30,12 +30,14 @@
|
|||
--ti-lowcode-className-selector-container-border-color: var(--ti-lowcode-base-gray-40);
|
||||
--ti-lowcode-className-selector-container-hover-border-color: var(--ti-lowcode-base-gray-90);
|
||||
--ti-lowcode-className-selector-container-empty-tips-color: var(--ti-lowcode-base-text-color-1);
|
||||
--ti-lowcode-className-selector-container-label-bg-color: var(--ti-lowcode-base-blue-6);
|
||||
--ti-lowcode-className-selector-container-option-btn-color: var(--ti-lowcode-base-gray-0);
|
||||
--ti-lowcode-className-selector-container-label-bg-color: rgba(20, 118, 255, 0.1);
|
||||
--ti-lowcode-className-selector-container-label-color: var(--ti-lowcode-base-primary-color-2);
|
||||
--ti-lowcode-className-selector-container-option-btn-color: var(--ti-lowcode-base-primary-color-2);
|
||||
--ti-lowcode-className-selector-dropdown-list-bg-color: var(--ti-lowcode-base-gray-0);
|
||||
--ti-lowcode-className-selector-dropdown-list-item-color: var(--ti-lowcode-base-text-color);
|
||||
--ti-lowcode-className-selector-dropdown-list-item-active-bg-color: var(--ti-lowcode-base-bg-2);
|
||||
--ti-lowcode-className-selector-dropdown-list-item-active-bg-color: var(--ti-lowcode-base-gray-20);
|
||||
--ti-lowcode-className-selector-title-color: var(--ti-lowcode-base-text-color);
|
||||
--ti-lowcode-className-selector-dropdown-list-tips-color: var(--ti-lowcode-base-text-color-3);
|
||||
}
|
||||
|
||||
:root {
|
||||
|
|
|
@ -50,11 +50,6 @@
|
|||
--ti-lowcode-component-svg-button-active-color: var(--ti-lowcode-base-text-color);
|
||||
--ti-lowcode-component-svg-button-active-bg-color: rgba(0, 0, 0, 0.05);
|
||||
|
||||
--ti-lowcode-meta-codeEditor-color: var(--ti-lowcode-component-btn-default-color);
|
||||
--ti-lowcode-meta-codeEditor-border-color: var(--ti-lowcode-component-btn-default-border-color);
|
||||
--ti-lowcode-meta-codeEditor-hover-color: var(--ti-lowcode-component-btn-default-hover-color);
|
||||
--ti-lowcode-meta-codeEditor-border-hover-color: var(--ti-lowcode-component-btn-default-border-hover-color);
|
||||
|
||||
// 关闭按钮
|
||||
--ti-lowcode-component-close-icon-text-color: var(--ti-lowcode-base-text-color); // 关闭按钮默认颜色
|
||||
--ti-lowcode-component-close-icon-text-hover-color: var(
|
||||
|
|
Loading…
Reference in New Issue