mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-02-17 17:40:31 +08:00
module can expose state
This commit is contained in:
parent
aee0af21db
commit
a0a75aca02
@ -17,6 +17,7 @@ type ModuleSpec = {
|
||||
components: ApplicationComponent[];
|
||||
properties: JSONSchema7Object;
|
||||
events: string[];
|
||||
stateMap: Record<string, string>;
|
||||
};
|
||||
|
||||
// extended runtime
|
||||
|
@ -1,13 +1,17 @@
|
||||
import { Static } from '@sinclair/typebox';
|
||||
import React from 'react';
|
||||
import { RuntimeApplication } from '@meta-ui/core';
|
||||
import { MetaUIServices } from '../../types/RuntimeSchema';
|
||||
import { MetaUIServices, RuntimeApplicationComponent } from '../../types/RuntimeSchema';
|
||||
import { EventHandlerSchema } from '../../types/TraitPropertiesSchema';
|
||||
import { parseTypeComponents } from '../chakra-ui/List';
|
||||
import { resolveAppComponents } from '../../services/resolveAppComponents';
|
||||
import { ImplWrapper } from '../../services/ImplWrapper';
|
||||
import { watch } from '../../utils/watchReactivity';
|
||||
import { get } from 'lodash';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export type RuntimeModuleSchema = {
|
||||
id: string;
|
||||
type: string;
|
||||
properties: Record<string, string>;
|
||||
handlers: Array<Static<typeof EventHandlerSchema>>;
|
||||
@ -20,10 +24,9 @@ type Props = RuntimeModuleSchema & {
|
||||
};
|
||||
|
||||
export const ModuleRenderer: React.FC<Props> = props => {
|
||||
const { type, properties, handlers, evalScope, services, app } = props;
|
||||
const moduleTemplate = services.registry.getModuleByType(type);
|
||||
const parsedtemplete = moduleTemplate.spec.components.map(parseTypeComponents);
|
||||
const { id, type, properties, handlers, evalScope, services, app } = props;
|
||||
|
||||
// first eval the property of module
|
||||
const { properties: moduleProperties, handlers: modulesHandlers } =
|
||||
services.stateManager.mapValuesDeep({ properties, handlers }, ({ value }) => {
|
||||
if (typeof value === 'string') {
|
||||
@ -32,15 +35,41 @@ export const ModuleRenderer: React.FC<Props> = props => {
|
||||
return value;
|
||||
});
|
||||
|
||||
const evaledModuleTemplate = services.stateManager.mapValuesDeep(
|
||||
{ template: parsedtemplete },
|
||||
({ value }) => {
|
||||
if (typeof value === 'string') {
|
||||
return services.stateManager.maskedEval(value, true, moduleProperties);
|
||||
const runtimeModule = services.registry.getModuleByType(type);
|
||||
const parsedtemplete = runtimeModule.spec.components.map(parseTypeComponents);
|
||||
// then eval the template and stateMap of module
|
||||
const { parsedtemplete: evaledModuleTemplate, stateMap: evaledStateMap } =
|
||||
services.stateManager.mapValuesDeep(
|
||||
{ parsedtemplete, stateMap: runtimeModule.spec.stateMap },
|
||||
({ value }) => {
|
||||
if (typeof value === 'string') {
|
||||
return services.stateManager.maskedEval(value, true, moduleProperties);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
);
|
||||
|
||||
// listen component state change
|
||||
useEffect(() => {
|
||||
const stops: ReturnType<typeof watch>[] = [];
|
||||
for (const stateKey in evaledStateMap) {
|
||||
const stop = watch(
|
||||
() => {
|
||||
return get(services.stateManager.store, evaledStateMap[stateKey]);
|
||||
},
|
||||
newV => {
|
||||
services.stateManager.store[id] = {
|
||||
...services.stateManager.store[id],
|
||||
[stateKey]: newV,
|
||||
};
|
||||
}
|
||||
);
|
||||
stops.push(stop);
|
||||
}
|
||||
).template;
|
||||
return () => {
|
||||
stops.forEach(s => s());
|
||||
};
|
||||
}, [evaledStateMap, services]);
|
||||
|
||||
const { topLevelComponents, slotComponentsMap } = resolveAppComponents(
|
||||
evaledModuleTemplate,
|
||||
|
@ -24,6 +24,7 @@ export function parseTypeComponents(
|
||||
}
|
||||
|
||||
const List: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
||||
component,
|
||||
listData,
|
||||
template,
|
||||
app,
|
||||
@ -49,6 +50,7 @@ const List: ComponentImplementation<Static<typeof PropsSchema>> = ({
|
||||
const listItemEle = (
|
||||
<BaseListItem key={listItem.id} spacing={3}>
|
||||
<ModuleRenderer
|
||||
id={`${component.id}ListItem${i}`}
|
||||
type={template.type}
|
||||
properties={template.properties}
|
||||
handlers={[]}
|
||||
|
@ -66,7 +66,6 @@ const exampleModule: RuntimeModule = {
|
||||
metadata: {
|
||||
name: 'littleItem',
|
||||
},
|
||||
// name: 'littleItem',
|
||||
spec: {
|
||||
components: [
|
||||
{
|
||||
@ -97,14 +96,9 @@ const exampleModule: RuntimeModule = {
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '{{$id}}2',
|
||||
type: 'core/v1/text',
|
||||
properties: {
|
||||
value: {
|
||||
raw: '**{{value2}}**',
|
||||
format: 'md',
|
||||
},
|
||||
},
|
||||
id: '{{$id}}input',
|
||||
type: 'chakra_ui/v1/input',
|
||||
properties: {},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
@ -120,6 +114,9 @@ const exampleModule: RuntimeModule = {
|
||||
],
|
||||
properties: {},
|
||||
events: [],
|
||||
stateMap: {
|
||||
value: '{{$id}}input.value',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user