Skip to content

Commit

Permalink
feat(editor,form,schema): 组件样式配置可视化
Browse files Browse the repository at this point in the history
  • Loading branch information
moonszhang authored and roymondchen committed Dec 30, 2024
1 parent ec94eed commit 246e694
Show file tree
Hide file tree
Showing 56 changed files with 1,491 additions and 312 deletions.
3 changes: 2 additions & 1 deletion packages/cli/tests/Core.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, test } from 'vitest';
import path from 'node:path';

import { describe, expect, test } from 'vitest';

import Core from '../src/Core';

describe('Core', () => {
Expand Down
7 changes: 5 additions & 2 deletions packages/design/src/Icon.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<template>
<component class="tmagic-design-icon" :is="uiComponent">
<component class="tmagic-design-icon" :is="uiComponent" v-bind="uiProps">
<slot></slot>
</component>
</template>

<script setup lang="ts">
import { computed } from 'vue';
import { getDesignConfig } from './config';
import { IconProps } from './types';
Expand All @@ -14,5 +16,6 @@ defineOptions({
const ui = getDesignConfig('components')?.icon;
const uiComponent = ui?.component || 'el-icon';
defineProps<IconProps>();
const props = defineProps<IconProps>();
const uiProps = computed(() => ui?.props(props) || props);
</script>
69 changes: 69 additions & 0 deletions packages/editor/src/fields/StyleSetter/Index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<template>
<div class="m-fields-style-setter">
<TMagicCollapse :model-value="collapseValue">
<template v-for="(item, index) in list" :key="index">
<TMagicCollapseItem :name="`${index}`">
<template #title><MIcon :icon="Grid"></MIcon>{{ item.title }}</template>
<component v-if="item.component" :is="item.component" :values="model[name]" @change="change"></component>
</TMagicCollapseItem>
</template>
</TMagicCollapse>
</div>
</template>

<script setup lang="ts">
import { shallowRef } from 'vue';
import { Grid } from '@element-plus/icons-vue';
import { TMagicCollapse, TMagicCollapseItem } from '@tmagic/design';
import type { ContainerChangeEventData, FieldProps } from '@tmagic/form';
import type { StyleSchema } from '@tmagic/schema';
import MIcon from '@editor/components/Icon.vue';
import { Background, Border, Font, Layout, Position } from './pro/';
defineOptions({
name: 'MFieldsStyleSetter',
});
defineProps<FieldProps<StyleSchema>>();
const emit = defineEmits<{
change: [v: any, eventData: ContainerChangeEventData];
}>();
const list = [
{
name: 'font',
title: '布局',
component: Layout,
},
{
title: '文字',
component: Font,
},
{
title: '背景',
component: Background,
},
{
title: '位置',
component: Position,
},
{
title: '边框与圆角',
component: Border,
},
];
const collapseValue = shallowRef(
Array(list.length)
.fill(1)
.map((x, i) => `${i}`),
);
const change = (v: any, eventData: ContainerChangeEventData) => {
emit('change', v, eventData);
};
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<template>
<div class="background-position-container">
<div class="presets-value-list">
<TMagicButton
v-for="(item, index) in list"
:key="index"
link
:class="model[name] === item.value && 'btn-active'"
@click="changeHandler(item.value)"
>
<div :class="['position-icon', item.class, model[name] === item.value && 'active']"></div>
</TMagicButton>
</div>
<div class="custom-value">
<TMagicInput v-model="model[name]" size="small" placeholder="自定义背景位置" clearable @change="changeHandler">
</TMagicInput>
</div>
</div>
</template>

<script lang="ts" setup>
import { TMagicButton, TMagicInput } from '@tmagic/design';
import type { FieldProps, FormItem } from '@tmagic/form';
const emit = defineEmits(['change']);
defineProps<FieldProps<{ type: 'style-setter' } & FormItem>>();
const horizontalList = [
{
value: 'left',
text: '',
},
{
value: 'center',
text: '',
},
{
value: 'right',
text: '',
},
];
const verticalList = [
{
value: 'top',
text: '',
},
{
value: 'center',
text: '',
},
{
value: 'bottom',
text: '',
},
];
const list = verticalList
.map((vertical) =>
horizontalList.map((horizontal) => ({
value: `${horizontal.value} ${vertical.value}`,
tips: `${horizontal.text}${vertical.text}`,
class: `${horizontal.value}-${vertical.value}`,
})),
)
.flat();
const changeHandler = (v: string) => {
emit('change', v);
};
</script>
104 changes: 104 additions & 0 deletions packages/editor/src/fields/StyleSetter/components/Border.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<template>
<div class="border-box-container">
<div class="border-icon-container">
<div class="border-icon-container-row">
<div
class="border-icon border-icon-top"
:class="{ active: direction === 'Top' }"
@click="selectDirection('Top')"
></div>
</div>
<div class="border-icon-container-row">
<div
class="border-icon border-icon-left"
:class="{ active: direction === 'Left' }"
@click="selectDirection('Left')"
></div>
<div class="border-icon" :class="{ active: direction === '' }" @click="selectDirection()"></div>
<div
class="border-icon border-icon-right"
:class="{ active: direction === 'Right' }"
@click="selectDirection('Right')"
></div>
</div>
<div class="border-icon-container-row">
<div
class="border-icon border-icon-bottom"
:class="{ active: direction === 'Bottom' }"
@click="selectDirection('Bottom')"
></div>
</div>
</div>
<div class="border-value-container">
<MContainer :config="config" :model="model" @change="change"></MContainer>
</div>
</div>
</template>

<script lang="ts" setup>
import { computed, ref } from 'vue';
import type { ContainerChangeEventData, FormValue } from '@tmagic/form';
import { MContainer } from '@tmagic/form';
import type { StyleSchema } from '@tmagic/schema';
const direction = ref('');
const config = computed(() => ({
items: [
{
name: `border${direction.value}Width`,
text: '边框宽度',
labelWidth: '68px',
type: 'data-source-field-select',
fieldConfig: {
type: 'text',
},
},
{
name: `border${direction.value}Color`,
text: '边框颜色',
labelWidth: '68px',
type: 'data-source-field-select',
fieldConfig: {
type: 'colorPicker',
},
},
{
name: `border${direction.value}Style`,
text: '边框样式',
labelWidth: '68px',
type: 'data-source-field-select',
fieldConfig: {
type: 'select',
options: ['solid', 'dashed', 'dotted'].map((item) => ({
value: item,
text: item,
})),
},
},
],
}));
const selectDirection = (d?: string) => (direction.value = d || '');
const emit = defineEmits<{
change: [v: StyleSchema, eventData: ContainerChangeEventData];
}>();
withDefaults(
defineProps<{
model: FormValue;
}>(),
{},
);
const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
eventData.changeRecords?.forEach((record) => {
emit('change', record.value, {
modifyKey: record.propPath,
});
});
};
</script>
68 changes: 68 additions & 0 deletions packages/editor/src/fields/StyleSetter/components/Box.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<template>
<div class="layout-box-container">
<div v-for="(item, index) in list" :key="index" :class="item.class">
<span class="help-txt" v-if="item.text">{{ item.text }}</span>
<span class="next-input">
<input v-model="model[item.name]" @change="change($event, item.name)" placeholder="0" />
</span>
</div>
</div>
</template>

<script lang="ts" setup>
import type { ContainerChangeEventData, FormValue } from '@tmagic/form';
const list = [
{
name: 'marginTop',
class: 'outer-top-border',
},
{
name: 'marginRight',
class: 'outer-right-border',
},
{
name: 'marginBottom',
text: 'MARGIN',
class: 'outer-bottom-border',
},
{
name: 'marginLeft',
class: 'outer-left-border',
},
{
name: 'paddingTop',
class: 'inner-top-border',
},
{
name: 'paddingRight',
class: 'inner-right-border',
},
{
name: 'paddingBottom',
text: 'PADDING',
class: 'inner-bottom-border',
},
{
name: 'paddingLeft',
class: 'inner-left-border',
},
];
const emit = defineEmits<{
change: [v: string, eventData: ContainerChangeEventData];
}>();
withDefaults(
defineProps<{
model: FormValue;
}>(),
{},
);
const change = (event: Event, name: string) => {
emit('change', (event.target as HTMLInputElement).value, {
modifyKey: name,
});
};
</script>
49 changes: 49 additions & 0 deletions packages/editor/src/fields/StyleSetter/components/Position.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<div class="layout-box-container">
<div v-for="(item, index) in list" :key="index" :class="item.class">
<span class="next-input">
<input v-model="model[item.name]" @change="change($event, item.name)" placeholder="0" />
</span>
</div>
</div>
</template>

<script lang="ts" setup>
import type { ContainerChangeEventData, FormValue } from '@tmagic/form';
const list = [
{
name: 'top',
class: 'outer-top-border',
},
{
name: 'right',
class: 'outer-right-border',
},
{
name: 'bottom',
class: 'outer-bottom-border',
},
{
name: 'left',
class: 'outer-left-border',
},
];
const emit = defineEmits<{
change: [v: string, eventData: ContainerChangeEventData];
}>();
withDefaults(
defineProps<{
model: FormValue;
}>(),
{},
);
const change = (event: Event, name: string) => {
emit('change', (event.target as HTMLInputElement).value, {
modifyKey: name,
});
};
</script>
Loading

0 comments on commit 246e694

Please sign in to comment.