add resolveTreeMap

This commit is contained in:
Bowen Tan 2022-01-05 13:55:27 +08:00
parent fdff89c1d5
commit f86a9c4781
3 changed files with 130 additions and 0 deletions

View File

@ -0,0 +1,93 @@
import { createApplication } from '@sunmao-ui/core';
import { resolveTreeMap } from '../src/utils/resolveTreeMap';
const origin = createApplication({
version: 'example/v1',
metadata: { name: 'dialog_component', description: 'dialog component example' },
spec: {
components: [
{
id: 'hstack1',
type: 'chakra_ui/v1/hstack',
properties: { spacing: '24px' },
traits: [],
},
{
id: 'button1',
type: 'chakra_ui/v1/button',
properties: {
text: { raw: 'text', format: 'plain' },
colorScheme: 'blue',
isLoading: false,
},
traits: [
{
type: 'core/v1/slot',
properties: { container: { id: 'hstack1', slot: 'content' } },
},
],
},
{
id: 'vstack1',
type: 'chakra_ui/v1/vstack',
properties: { spacing: '24px' },
traits: [
{
type: 'core/v1/slot',
properties: { container: { id: 'hstack1', slot: 'content' } },
},
],
},
{
id: 'hstack2',
type: 'chakra_ui/v1/hstack',
properties: { spacing: '24px' },
traits: [
{
type: 'core/v1/slot',
properties: { container: { id: 'vstack1', slot: 'content' } },
},
],
},
{
id: 'text1',
type: 'core/v1/text',
properties: { value: { raw: 'text', format: 'plain' } },
traits: [
{
type: 'core/v1/slot',
properties: { container: { id: 'hstack2', slot: 'content' } },
},
],
},
{
id: 'text2',
type: 'core/v1/text',
properties: { value: { raw: 'text', format: 'plain' } },
traits: [
{
type: 'core/v1/slot',
properties: { container: { id: 'hstack2', slot: 'content' } },
},
],
},
{
id: 'hstack3',
type: 'chakra_ui/v1/hstack',
properties: { spacing: '24px' },
traits: [],
},
],
},
});
describe('resolve tree map', () => {
const {treeMap, topLevelComponents} = resolveTreeMap(origin.spec.components)
it('resolve tree map', () => {
expect(treeMap['hstack1'].content.map(c => c.id)).toEqual(['button1', 'vstack1']);
expect(treeMap['vstack1'].content.map(c => c.id)).toEqual(['hstack2']);
expect(treeMap['hstack2'].content.map(c => c.id)).toEqual(['text1', 'text2']);
expect(topLevelComponents.map(c => c.id)).toEqual(['hstack1', 'hstack3']);
});
});

View File

@ -46,12 +46,18 @@ export type ImplWrapperProps<KSlot extends string = string> = {
component: RuntimeApplicationComponent;
// TODO: (type-safe), remove slotsMap from props
slotsMap: SlotsMap<KSlot> | undefined;
treeMap: TreeMap<KSlot>;
Slot: SlotType<KSlot>;
targetSlot: { id: string; slot: string } | null;
services: UIServices;
app?: RuntimeApplication;
} & ComponentParamsFromApp;
export type TreeMap<KSlot extends string> = Record<
string,
Record<KSlot, RuntimeApplicationComponent[]>
>;
export type SlotComponentMap = Map<string, SlotsMap<string>>;
export type SlotsMap<K extends string> = Map<
K,

View File

@ -0,0 +1,31 @@
import { RuntimeApplicationComponent, TreeMap } from '../types/RuntimeSchema';
export function resolveTreeMap(components: RuntimeApplicationComponent[]): {
treeMap: TreeMap<string>;
topLevelComponents: RuntimeApplicationComponent[];
} {
const treeMap: TreeMap<string> = {};
const topLevelComponents: RuntimeApplicationComponent[] = [];
for (const c of components) {
const slotTrait = c.traits.find(t => t.parsedType.name === 'slot');
if (!slotTrait) {
topLevelComponents.push(c)
continue;
}
const { id, slot } = slotTrait.properties.container as any;
if (!treeMap[id]) {
treeMap[id] = {};
}
const children = treeMap[id];
if (!children[slot]) {
children[slot] = [];
}
const slotChildren = children[slot];
slotChildren.push(c);
}
return {
treeMap,
topLevelComponents,
};
}