feat(图表): 背景设置内边距和圆角支持分开设置

This commit is contained in:
wisonic-s
2025-11-19 18:52:14 +08:00
committed by wisonic-s
parent 73cdf537f9
commit 73c794d31e
9 changed files with 469 additions and 38 deletions

View File

@@ -158,6 +158,11 @@ import {
import Board from '@/components/de-board/Board.vue'
import { activeWatermarkCheckUser, removeActiveWatermark } from '@/components/watermark/watermark'
import { useI18n } from '@/hooks/web/useI18n'
import {
CommonBackground,
ShorthandMode
} from '@/components/visualization/component-background/Types'
const { t } = useI18n()
const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
@@ -962,10 +967,34 @@ const componentBackgroundStyle = computed(() => {
innerPadding,
borderRadius
} = element.value.commonBackground
const commonBackground = element.value.commonBackground as CommonBackground
const innerPaddingTarget = ['Group'].includes(element.value.component) ? 0 : innerPadding
let innerPaddingStyle = innerPaddingTarget * scale.value + 'px'
const paddingMode = commonBackground.innerPadding?.mode
if (paddingMode === ShorthandMode.Uniform) {
innerPaddingStyle = `${commonBackground.innerPadding?.top * scale.value}px`
} else if (paddingMode === ShorthandMode.PerEdge) {
innerPaddingStyle = `${commonBackground.innerPadding?.top * scale.value}px ${
commonBackground.innerPadding?.right * scale.value
}px ${commonBackground.innerPadding?.bottom * scale.value}px ${
commonBackground.innerPadding?.left * scale.value
}px`
}
let borderRadiusStyle = borderRadius + 'px'
const borderRadiusMode = commonBackground.borderRadius?.mode
if (borderRadiusMode === ShorthandMode.Uniform) {
borderRadiusStyle = `${commonBackground.borderRadius?.topLeft * scale.value}px`
} else if (borderRadiusMode === ShorthandMode.PerEdge) {
borderRadiusStyle = `${commonBackground.borderRadius?.topLeft * scale.value}px ${
commonBackground.borderRadius?.topRight * scale.value
}px ${commonBackground.borderRadius?.bottomRight * scale.value}px ${
commonBackground.borderRadius?.bottomLeft * scale.value
}px`
}
let style = {
padding: innerPaddingTarget * scale.value + 'px',
borderRadius: borderRadius + 'px'
padding: innerPaddingStyle,
borderRadius: borderRadiusStyle
}
let colorRGBA = ''
if (backgroundColorSelect && backgroundColor) {

View File

@@ -15,38 +15,192 @@
/>
<el-form size="small" label-position="top" style="width: 100%">
<el-row :gutter="8">
<el-col :span="12">
<el-col :span="24">
<el-form-item
:label="t('visualization.inner_padding')"
class="form-item w100"
:class="'form-item-' + themes"
>
<el-input-number
style="width: 100%"
:effect="themes"
controls-position="right"
:min="0"
:max="100"
v-model="state.commonBackground.innerPadding"
@change="onBackgroundChange"
/>
<div style="display: flex; align-items: center; width: 100%; margin-bottom: 8px">
<span style="width: 15%; padding-right: 8px">{{
t('visualization.inner_padding_shorthand_mode')
}}</span>
<el-select
:effect="themes"
v-model="state.commonBackground.innerPadding.mode"
size="small"
style="width: 85%"
@change="onBackgroundChange"
>
<el-option
class="custom-style-option"
v-for="option in paddingModes"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select>
</div>
<el-row :gutter="8">
<el-col :span="12">
<div style="display: flex; align-items: center; margin-bottom: 8px">
<span style="width: 30%; padding-right: 8px">{{
t('visualization.edge_top')
}}</span>
<el-input-number
style="width: 70%"
:effect="themes"
controls-position="right"
:min="0"
:max="100"
v-model="state.commonBackground.innerPadding.top"
@change="onBackgroundChange"
/>
</div>
<div style="display: flex; align-items: center">
<span style="width: 30%; padding-right: 8px">{{
t('visualization.edge_left')
}}</span>
<el-input-number
style="width: 70%"
:effect="themes"
controls-position="right"
:min="0"
:max="100"
v-model="state.commonBackground.innerPadding.left"
:disabled="state.commonBackground.innerPadding.mode === ShorthandMode.Uniform"
@change="onBackgroundChange"
/>
</div>
</el-col>
<el-col :span="12">
<div style="display: flex; align-items: center; margin-bottom: 8px">
<span style="width: 30%; padding-right: 8px">{{
t('visualization.edge_bottom')
}}</span>
<el-input-number
style="width: 70%"
:effect="themes"
:disabled="state.commonBackground.innerPadding.mode !== ShorthandMode.PerEdge"
controls-position="right"
:min="0"
:max="100"
v-model="state.commonBackground.innerPadding.bottom"
@change="onBackgroundChange"
/>
</div>
<div style="display: flex; align-items: center">
<span style="width: 30%; padding-right: 8px">{{
t('visualization.edge_right')
}}</span>
<el-input-number
style="width: 70%"
:effect="themes"
:disabled="state.commonBackground.innerPadding.mode !== ShorthandMode.PerEdge"
controls-position="right"
:min="0"
:max="100"
v-model="state.commonBackground.innerPadding.right"
@change="onBackgroundChange"
/>
</div>
</el-col>
</el-row>
</el-form-item>
</el-col>
<el-col :span="12">
</el-row>
<el-row :gutter="8">
<el-col :span="24">
<el-form-item
:label="t('visualization.board_radio')"
class="form-item w100"
:class="'form-item-' + themes"
>
<el-input-number
style="width: 100%"
:effect="themes"
controls-position="right"
:min="0"
:max="100"
v-model="state.commonBackground.borderRadius"
@change="onBackgroundChange"
/>
<div style="display: flex; align-items: center; width: 100%; margin-bottom: 8px">
<span style="width: 15%; padding-right: 8px">{{
t('visualization.corner_shorthand_mode')
}}</span>
<el-select
:effect="themes"
v-model="state.commonBackground.borderRadius.mode"
size="small"
style="width: 85%"
@change="onBackgroundChange"
>
<el-option
class="custom-style-option"
v-for="option in cornerModes"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select>
</div>
<el-row :gutter="8">
<el-col :span="12">
<div style="display: flex; align-items: center; margin-bottom: 8px">
<span style="width: 30%; padding-right: 8px">{{
t('visualization.corner_top_left')
}}</span>
<el-input-number
style="width: 70%"
:effect="themes"
controls-position="right"
:min="0"
:max="100"
v-model="state.commonBackground.borderRadius.topLeft"
@change="onBackgroundChange"
/>
</div>
<div style="display: flex; align-items: center">
<span style="width: 30%; padding-right: 8px">{{
t('visualization.corner_bottom_left')
}}</span>
<el-input-number
style="width: 70%"
:effect="themes"
controls-position="right"
:min="0"
:max="100"
v-model="state.commonBackground.borderRadius.bottomLeft"
:disabled="state.commonBackground.borderRadius.mode === ShorthandMode.Uniform"
@change="onBackgroundChange"
/>
</div>
</el-col>
<el-col :span="12">
<div style="display: flex; align-items: center; margin-bottom: 8px">
<span style="width: 30%; padding-right: 8px">{{
t('visualization.corner_top_right')
}}</span>
<el-input-number
style="width: 70%"
:effect="themes"
:disabled="state.commonBackground.borderRadius.mode !== ShorthandMode.PerEdge"
controls-position="right"
:min="0"
:max="100"
v-model="state.commonBackground.borderRadius.topRight"
@change="onBackgroundChange"
/>
</div>
<div style="display: flex; align-items: center">
<span style="width: 30%; padding-right: 8px">{{
t('visualization.corner_bottom_right')
}}</span>
<el-input-number
style="width: 70%"
:effect="themes"
:disabled="state.commonBackground.borderRadius.mode !== ShorthandMode.PerEdge"
controls-position="right"
:min="0"
:max="100"
v-model="state.commonBackground.borderRadius.bottomRight"
@change="onBackgroundChange"
/>
</div>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
@@ -218,7 +372,7 @@
class="image-hint"
:class="`image-hint_${themes}`"
>
支持JPGPNGGIFSVG
{{ t('visualization.panel_background_image_tips') }}
</span>
<el-button
@@ -229,7 +383,7 @@
@click="goFile"
:disabled="!state.commonBackground.backgroundImageEnable"
>
重新上传
{{ t('visualization.reUpload') }}
</el-button>
</el-row>
</div>
@@ -244,7 +398,7 @@
<script setup lang="ts">
import { queryVisualizationBackground } from '@/api/visualization/visualizationBackground'
import { COLOR_PANEL } from '@/views/chart/components/editor/util/chart'
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
import { computed, effect, nextTick, onMounted, reactive, ref, watch } from 'vue'
import { imgUrlTrans } from '@/utils/imgUtils'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import { beforeUploadCheck, uploadFileResult } from '@/api/staticResource'
@@ -255,6 +409,8 @@ import { ElMessage } from 'element-plus-secondary'
import BoardItem from '@/components/visualization/component-background/BoardItem.vue'
import ImgViewDialog from '@/custom-component/ImgViewDialog.vue'
import BorderOptionPrefix from '@/components/visualization/component-background/BorderOptionPrefix.vue'
import { State, ShorthandMode } from '@/components/visualization/component-background/Types'
const snapshotStore = snapshotStoreWithOut()
const { t } = useI18n()
const emits = defineEmits(['onBackgroundChange'])
@@ -279,8 +435,11 @@ const props = withDefaults(
}
)
const state = reactive({
commonBackground: {},
const state = reactive<State>({
commonBackground: {
innerPadding: {},
borderRadius: {}
},
BackgroundShowMap: {},
checked: false,
backgroundOrigin: {},
@@ -292,6 +451,16 @@ const state = reactive({
predefineColors: COLOR_PANEL
})
const paddingModes = Object.values(ShorthandMode).map(item => ({
label: t(`visualization.inner_padding_shorthand_mode_${item}`),
value: item
})) as { label: string; value: ShorthandMode }[]
const cornerModes = Object.values(ShorthandMode).map(item => ({
label: t(`visualization.corner_shorthand_mode_${item}`),
value: item
})) as { label: string; value: ShorthandMode }[]
const goFile = () => {
files.value.click()
}
@@ -320,7 +489,30 @@ const queryBackground = () => {
}
const init = () => {
state.commonBackground = deepCopy(props.commonBackgroundPop)
const commonBackgroundPop = deepCopy(props.commonBackgroundPop)
const innerPadding = commonBackgroundPop.innerPadding
if (typeof innerPadding === 'number') {
commonBackgroundPop.innerPadding = {
mode: ShorthandMode.Uniform,
top: innerPadding,
right: innerPadding,
bottom: innerPadding,
left: innerPadding
}
}
const borderRadius = commonBackgroundPop.borderRadius
if (typeof borderRadius === 'number') {
commonBackgroundPop.borderRadius = {
mode: ShorthandMode.Uniform,
topLeft: borderRadius,
topRight: borderRadius,
bottomLeft: borderRadius,
bottomRight: borderRadius
}
}
state.commonBackground = commonBackgroundPop
updateInnerPadding()
updateBorderRadius()
if (state.commonBackground['outerImage']) {
state.fileList = [{ url: imgUrlTrans(state.commonBackground['outerImage']) }]
} else {
@@ -350,7 +542,25 @@ const upload = file => {
})
}
const updateInnerPadding = () => {
if (state.commonBackground.innerPadding.mode === ShorthandMode.Uniform) {
state.commonBackground.innerPadding.left = state.commonBackground.innerPadding.top
state.commonBackground.innerPadding.right = state.commonBackground.innerPadding.top
state.commonBackground.innerPadding.bottom = state.commonBackground.innerPadding.top
}
}
const updateBorderRadius = () => {
if (state.commonBackground.borderRadius.mode === ShorthandMode.Uniform) {
state.commonBackground.borderRadius.topRight = state.commonBackground.borderRadius.topLeft
state.commonBackground.borderRadius.bottomLeft = state.commonBackground.borderRadius.topLeft
state.commonBackground.borderRadius.bottomRight = state.commonBackground.borderRadius.topLeft
}
}
const onBackgroundChange = () => {
updateInnerPadding()
updateBorderRadius()
emits('onBackgroundChange', state.commonBackground)
}
@@ -477,13 +687,13 @@ watch(
align-items: center;
}
.ed-select-dropdown__item {
.board-select .ed-select-dropdown__item {
height: 100px !important;
text-align: center;
padding: 0px 5px;
}
.ed-select-dropdown__item.selected::after {
.board-select .ed-select-dropdown__item.selected::after {
display: none;
}

View File

@@ -0,0 +1,61 @@
import { COLOR_PANEL } from '@/views/chart/components/editor/util/chart'
import type { UploadFile } from 'element-plus-secondary'
/**
* 简写模式枚举,用于定义不同的边值设置模式
*/
export enum ShorthandMode {
/**
* 统一模式,所有边使用相同的值
*/
Uniform = 'uniform',
/**
* 逐边模式,可单独设置每条边的值
*/
PerEdge = 'per_edge'
}
export interface EdgeValues {
mode?: ShorthandMode
top?: number
right?: number
bottom?: number
left?: number
}
export interface CornerValues {
mode?: ShorthandMode
topLeft?: number
topRight?: number
bottomLeft?: number
bottomRight?: number
}
export type BackgroundType = 'outerImage' | 'innerImage'
export interface CommonBackground {
innerPadding?: EdgeValues
borderRadius?: CornerValues
backdropFilterEnable?: boolean
backdropFilter?: number
backgroundColorSelect?: boolean
backgroundColor?: string
backgroundImageEnable?: boolean
backgroundType?: BackgroundType
innerImageColor?: string
innerImage?: string
outerImage?: string
}
export interface State {
commonBackground: CommonBackground
BackgroundShowMap: Record<string, any>
checked: boolean
backgroundOrigin: Record<string, any>
fileList: UploadFile[]
dialogImageUrl: string
dialogVisible: boolean
uploadDisabled: boolean
panel?: any
predefineColors: typeof COLOR_PANEL
}

View File

@@ -3,6 +3,10 @@ import { deepCopy } from '@/utils/utils'
import { guid } from '@/views/visualized/data/dataset/form/util'
import { getViewConfig } from '@/views/chart/components/editor/util/chart'
import { useI18n } from '@/hooks/web/useI18n'
import {
CommonBackground,
ShorthandMode
} from '@/components/visualization/component-background/Types'
const { t } = useI18n()
export const commonStyle = {
@@ -177,15 +181,21 @@ export const MULTI_DIMENSIONAL = {
z: 0
}
export const COMMON_COMPONENT_BACKGROUND_BASE = {
export const COMMON_COMPONENT_BACKGROUND_BASE: CommonBackground = {
backgroundColorSelect: true,
backdropFilterEnable: false,
backgroundImageEnable: false,
backgroundType: 'innerImage',
innerImage: 'board/board_1.svg',
outerImage: null,
innerPadding: 12,
borderRadius: 0,
innerPadding: {
mode: ShorthandMode.Uniform,
top: 12
},
borderRadius: {
mode: ShorthandMode.Uniform,
topLeft: 0
},
backdropFilter: 4
}

View File

@@ -176,6 +176,11 @@ import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapsho
import { useI18n } from '@/hooks/web/useI18n'
import { imgUrlTrans } from '@/utils/imgUtils'
import Board from '@/components/de-board/Board.vue'
import {
CommonBackground,
ShorthandMode
} from '@/components/visualization/component-background/Types'
const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
const { tabMoveInActiveId, bashMatrixInfo, editMode, mobileInPc } = storeToRefs(dvMainStore)
@@ -504,9 +509,34 @@ const backgroundStyle = backgroundParams => {
innerPadding,
borderRadius
} = backgroundParams
const commonBackground = backgroundParams as CommonBackground
const innerPaddingTarget = ['Group'].includes(element.value.component) ? 0 : innerPadding
let innerPaddingStyle = innerPaddingTarget * scale.value + 'px'
const paddingMode = commonBackground.innerPadding?.mode
if (paddingMode === ShorthandMode.Uniform) {
innerPaddingStyle = `${commonBackground.innerPadding?.top * scale.value}px`
} else if (paddingMode === ShorthandMode.PerEdge) {
innerPaddingStyle = `${commonBackground.innerPadding?.top * scale.value}px ${
commonBackground.innerPadding?.right * scale.value
}px ${commonBackground.innerPadding?.bottom * scale.value}px ${
commonBackground.innerPadding?.left * scale.value
}px`
}
let borderRadiusStyle = borderRadius + 'px'
const borderRadiusMode = commonBackground.borderRadius?.mode
if (borderRadiusMode === ShorthandMode.Uniform) {
borderRadiusStyle = `${commonBackground.borderRadius?.topLeft * scale.value}px`
} else if (borderRadiusMode === ShorthandMode.PerEdge) {
borderRadiusStyle = `${commonBackground.borderRadius?.topLeft * scale.value}px ${
commonBackground.borderRadius?.topRight * scale.value
}px ${commonBackground.borderRadius?.bottomRight * scale.value}px ${
commonBackground.borderRadius?.bottomLeft * scale.value
}px`
}
let style = {
padding: innerPadding * scale.value + 'px',
borderRadius: borderRadius + 'px'
padding: innerPaddingStyle,
borderRadius: borderRadiusStyle
}
let colorRGBA = ''
if (backgroundColorSelect && backgroundColor) {

View File

@@ -3381,7 +3381,23 @@ export default {
stream_mobile_tips: 'May not be displayed on IOS devices',
json_params_error: 'Failed to parse third-party parameters. Please check the parameter format.',
inner_padding: 'Inner Padding',
inner_padding_shorthand_mode: 'Mode',
inner_padding_shorthand_mode_uniform: 'Uniform',
inner_padding_shorthand_mode_axis: 'Axis',
inner_padding_shorthand_mode_per_edge: 'Per Edge',
edge_top: 'Top',
edge_right: 'Right',
edge_bottom: 'Bottom',
edge_left: 'Left',
board_radio: 'Corners',
corner_shorthand_mode: 'Mode',
corner_shorthand_mode_uniform: 'Uniform',
corner_shorthand_mode_axis: 'Diagonal',
corner_shorthand_mode_per_edge: 'Per Corner',
corner_top_left: 'Top Left',
corner_top_right: 'Top Right',
corner_bottom_left: 'Bottom Left',
corner_bottom_right: 'Bottom Right',
web_set_tips: 'Some websites may not allow embedding and will not display.',
repeat_params: 'Duplicate parameter names exist.',
enable_outer_param_set: 'Enable External Parameter Settings',

View File

@@ -3284,7 +3284,23 @@ export default {
stream_mobile_tips: 'IOS終端可能無法顯示',
json_params_error: '第三方參數解析失敗,請檢查參數格式是否正確',
inner_padding: '內邊距',
inner_padding_shorthand_mode: '模式',
inner_padding_shorthand_mode_uniform: '統一值',
inner_padding_shorthand_mode_axis: '軸向',
inner_padding_shorthand_mode_per_edge: '逐邊',
edge_top: '上',
edge_right: '右',
edge_bottom: '下',
edge_left: '左',
board_radio: '圓角',
corner_shorthand_mode: '模式',
corner_shorthand_mode_uniform: '統一值',
corner_shorthand_mode_axis: '對角',
corner_shorthand_mode_per_edge: '逐角',
corner_top_left: '左上',
corner_top_right: '右上',
corner_bottom_left: '左下',
corner_bottom_right: '右下',
web_set_tips: '部分網站可能設置不允許嵌入而無法顯示',
repeat_params: '存在名稱重複的參數',
enable_outer_param_set: '啟用外部參數設置',

View File

@@ -3290,7 +3290,23 @@ export default {
stream_mobile_tips: 'IOS终端可能无法显示',
json_params_error: '第三方参数解析失败,请检查参数格式是否正确',
inner_padding: '内边距',
inner_padding_shorthand_mode: '模式',
inner_padding_shorthand_mode_uniform: '统一值',
inner_padding_shorthand_mode_axis: '轴向',
inner_padding_shorthand_mode_per_edge: '逐边',
edge_top: '上',
edge_right: '右',
edge_bottom: '下',
edge_left: '左',
board_radio: '圆角',
corner_shorthand_mode: '模式',
corner_shorthand_mode_uniform: '统一值',
corner_shorthand_mode_axis: '对角',
corner_shorthand_mode_per_edge: '逐角',
corner_top_left: '左上',
corner_top_right: '右上',
corner_bottom_left: '左下',
corner_bottom_right: '右下',
web_set_tips: '部分网站可能设置不允许嵌入而无法显示',
repeat_params: '存在名称重复的参数',
enable_outer_param_set: '启用外部参数设置',

View File

@@ -31,6 +31,7 @@ import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapsho
import { deepCopy, nameTrim } from '@/utils/utils'
import { ElMessage, ElMessageBox } from 'element-plus-secondary'
import { guid } from '@/views/visualized/data/dataset/form/util'
import { ShorthandMode } from '@/components/visualization/component-background/Types'
const dvMainStore = dvMainStoreWithOut()
const {
inMobile,
@@ -48,6 +49,27 @@ import { isDesktop } from '@/utils/ModelUtil'
const { t } = useI18n()
const appearanceStore = useAppearanceStoreWithOut()
const { wsCache } = useCache()
const getNewInnerPadding = (commonGap = 0) => {
return {
mode: ShorthandMode.Uniform,
top: commonGap,
right: commonGap,
bottom: commonGap,
left: commonGap
}
}
const getNewBorderRadius = (commonGap = 0) => {
return {
mode: ShorthandMode.Uniform,
topLeft: commonGap,
topRight: commonGap,
bottomLeft: commonGap,
bottomRight: commonGap
}
}
export function chartTransStr2Object(targetIn, copy) {
const target = copy === 'Y' ? cloneDeep(targetIn) : targetIn
return target
@@ -98,7 +120,7 @@ export function findNewComponent(componentName, innerType, staticMap?) {
}
} else if (['DeDecoration', 'DynamicBackground'].includes(componentName)) {
newComponent.style.borderWidth = 0
newComponent.style.innerPadding = 0
newComponent.style.innerPadding = getNewInnerPadding()
}
return newComponent
}
@@ -120,6 +142,10 @@ export function commonHandleDragEnd(e, dvModel) {
}
}
function isNumber(value) {
return !isNaN(value) && typeof value === 'number'
}
function matrixAdaptor(componentItem) {
componentItem.x = 1 + (componentItem.x - 1) * 2
componentItem.y = 1 + (componentItem.y - 1) * 2
@@ -166,7 +192,19 @@ export function historyItemAdaptor(
}
})
}
// 历史innerPadding 转换
if (isNumber(componentItem['commonBackground'].innerPadding)) {
componentItem['commonBackground'].innerPadding = getNewInnerPadding(
componentItem['commonBackground'].innerPadding
)
}
// 历史borderRadius 转换
if (isNumber(componentItem['commonBackground'].borderRadius)) {
componentItem['commonBackground'].borderRadius = getNewBorderRadius(
componentItem['commonBackground'].borderRadius
)
}
if (componentItem.component === 'DeTabs') {
componentItem.style['showTabTitle'] =
componentItem.style['showTabTitle'] === undefined ? true : componentItem.style['showTabTitle']
@@ -183,14 +221,19 @@ export function historyItemAdaptor(
if (componentItem.style['borderActive'] === undefined) {
componentItem.style['borderActive'] = false
componentItem.style['borderWidth'] = 1
componentItem.style['borderRadius'] = 5
componentItem.style['borderRadius'] = getNewBorderRadius(5)
componentItem.style['borderStyle'] = 'solid'
componentItem.style['borderColor'] = '#cccccc'
} else {
componentItem.style['borderWidth'] =
componentItem.style['borderWidth'] === undefined ? 1 : componentItem.style['borderWidth']
componentItem.style['borderRadius'] =
componentItem.style['borderRadius'] === undefined ? 5 : componentItem.style['borderRadius']
componentItem.style['borderRadius'] === undefined
? getNewBorderRadius(5)
: componentItem.style['borderRadius']
if (isNumber(componentItem.style['borderRadius'])) {
componentItem.style['borderRadius'] = getNewBorderRadius(componentItem.style['borderRadius'])
}
componentItem.style['borderStyle'] =
componentItem.style['borderStyle'] === undefined
? 'solid'