mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2024-11-21 03:15:49 +08:00
remove slotsMap & resolveAppComponents
This commit is contained in:
parent
7192c5cd7c
commit
edf4b2b9d9
@ -39,22 +39,23 @@ export default implementRuntimeComponent({
|
|||||||
mergeState,
|
mergeState,
|
||||||
subscribeMethods,
|
subscribeMethods,
|
||||||
hideSubmit,
|
hideSubmit,
|
||||||
slotsMap,
|
|
||||||
callbackMap,
|
callbackMap,
|
||||||
services,
|
services,
|
||||||
customStyle,
|
customStyle,
|
||||||
Slot,
|
Slot,
|
||||||
|
treeMap,
|
||||||
|
component
|
||||||
}) => {
|
}) => {
|
||||||
const [invalidArray, setInvalidArray] = useState<boolean[]>([]);
|
const [invalidArray, setInvalidArray] = useState<boolean[]>([]);
|
||||||
const [isFormInvalid, setIsFormInvalid] = useState<boolean>(false);
|
const [isFormInvalid, setIsFormInvalid] = useState<boolean>(false);
|
||||||
const formDataRef = useRef<Record<string, any>>({});
|
const formDataRef = useRef<Record<string, any>>({});
|
||||||
const formControlIds = useMemo<string[]>(() => {
|
const formControlIds = useMemo<string[]>(() => {
|
||||||
return (
|
return (
|
||||||
slotsMap?.get('content')?.map(slot => {
|
treeMap[component.id]?.content.map(slot => {
|
||||||
return slot.id;
|
return slot.id;
|
||||||
}) || []
|
}) || []
|
||||||
);
|
);
|
||||||
}, [slotsMap]);
|
}, [component.id, treeMap]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInvalidArray(
|
setInvalidArray(
|
||||||
|
@ -60,16 +60,17 @@ export default implementRuntimeComponent({
|
|||||||
fieldName,
|
fieldName,
|
||||||
isRequired,
|
isRequired,
|
||||||
helperText,
|
helperText,
|
||||||
slotsMap,
|
|
||||||
mergeState,
|
mergeState,
|
||||||
services,
|
services,
|
||||||
customStyle,
|
customStyle,
|
||||||
Slot,
|
Slot,
|
||||||
|
treeMap,
|
||||||
|
component,
|
||||||
}) => {
|
}) => {
|
||||||
const [inputValue, setInputValue] = useState('');
|
const [inputValue, setInputValue] = useState('');
|
||||||
// don't show Invalid state on component mount
|
// don't show Invalid state on component mount
|
||||||
const [hideInvalid, setHideInvalid] = useState(true);
|
const [hideInvalid, setHideInvalid] = useState(true);
|
||||||
const inputId = useMemo(() => first(slotsMap?.get('content'))?.id || '', [slotsMap]);
|
const inputId = useMemo(() => first(treeMap[component.id].content)?.id || '', [component.id, treeMap]);
|
||||||
const [validResult, setValidResult] = useState({
|
const [validResult, setValidResult] = useState({
|
||||||
isInvalid: false,
|
isInvalid: false,
|
||||||
errorMsg: '',
|
errorMsg: '',
|
||||||
|
@ -82,7 +82,7 @@ export default implementRuntimeComponent({
|
|||||||
${customStyle?.tabContent}
|
${customStyle?.tabContent}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
{<Component /> || placeholder}
|
{Component ? <Component /> : placeholder}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -26,10 +26,10 @@ export const ComponentTree: React.FC<Props> = props => {
|
|||||||
if (slots.length === 0) {
|
if (slots.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const slotsMap = childrenMap.get(component.id);
|
const children = childrenMap.get(component.id);
|
||||||
return slots.map(slot => {
|
return slots.map(slot => {
|
||||||
let slotContent;
|
let slotContent;
|
||||||
const slotChildren = slotsMap?.get(slot);
|
const slotChildren = children?.get(slot);
|
||||||
if (slotChildren && slotChildren.length > 0) {
|
if (slotChildren && slotChildren.length > 0) {
|
||||||
slotContent = slotChildren.map(c => {
|
slotContent = slotChildren.map(c => {
|
||||||
return (
|
return (
|
||||||
|
@ -3,7 +3,6 @@ import { ApplicationComponent } from '@sunmao-ui/core';
|
|||||||
export type ChildrenMap = Map<string, SlotsMap>;
|
export type ChildrenMap = Map<string, SlotsMap>;
|
||||||
type SlotsMap = Map<string, ApplicationComponent[]>;
|
type SlotsMap = Map<string, ApplicationComponent[]>;
|
||||||
|
|
||||||
// similar to resolveAppComponents
|
|
||||||
export function resolveApplicationComponents(components: ApplicationComponent[]): {
|
export function resolveApplicationComponents(components: ApplicationComponent[]): {
|
||||||
topLevelComponents: ApplicationComponent[];
|
topLevelComponents: ApplicationComponent[];
|
||||||
childrenMap: ChildrenMap;
|
childrenMap: ChildrenMap;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React, { useMemo, useRef } from 'react';
|
import React, { useRef } from 'react';
|
||||||
import { initStateAndMethod } from './utils/initStateAndMethod';
|
import { initStateAndMethod } from './utils/initStateAndMethod';
|
||||||
import { ImplWrapper } from './components/_internal/ImplWrapper';
|
import { ImplWrapper } from './components/_internal/ImplWrapper';
|
||||||
import { resolveAppComponents } from './services/resolveAppComponents';
|
|
||||||
import { AppProps, UIServices } from './types/RuntimeSchema';
|
import { AppProps, UIServices } from './types/RuntimeSchema';
|
||||||
import { DebugEvent, DebugStore } from './services/DebugComponents';
|
import { DebugEvent, DebugStore } from './services/DebugComponents';
|
||||||
import { RuntimeAppSchemaManager } from './services/RuntimeAppSchemaManager';
|
import { RuntimeAppSchemaManager } from './services/RuntimeAppSchemaManager';
|
||||||
@ -28,37 +27,16 @@ export const App: React.FC<AppProps> = props => {
|
|||||||
|
|
||||||
initStateAndMethod(services.registry, services.stateManager, app.spec.components);
|
initStateAndMethod(services.registry, services.stateManager, app.spec.components);
|
||||||
|
|
||||||
const { topLevelComponents, slotComponentsMap } = useMemo(
|
const { treeMap, topLevelComponents } = resolveTreeMap(app.spec.components);
|
||||||
() =>
|
|
||||||
resolveAppComponents(app.spec.components, {
|
|
||||||
services,
|
|
||||||
app,
|
|
||||||
componentWrapper,
|
|
||||||
gridCallbacks,
|
|
||||||
}),
|
|
||||||
[app, componentWrapper, gridCallbacks, services]
|
|
||||||
);
|
|
||||||
|
|
||||||
const { treeMap } = resolveTreeMap(app.spec.components);
|
|
||||||
return (
|
return (
|
||||||
<div className="App" style={{ height: '100vh', overflow: 'auto' }}>
|
<div className="App" style={{ height: '100vh', overflow: 'auto' }}>
|
||||||
{topLevelComponents.map(c => {
|
{topLevelComponents.map(c => {
|
||||||
const slotsMap = slotComponentsMap.get(c.id);
|
|
||||||
// const Slot = genSlot({
|
|
||||||
// component: c,
|
|
||||||
// slotsMap,
|
|
||||||
// treeMap,
|
|
||||||
// ...props,
|
|
||||||
// });
|
|
||||||
return (
|
return (
|
||||||
<ImplWrapper
|
<ImplWrapper
|
||||||
key={c.id}
|
key={c.id}
|
||||||
component={c}
|
component={c}
|
||||||
services={services}
|
services={services}
|
||||||
slotsMap={slotsMap}
|
|
||||||
Slot={() => null}
|
|
||||||
treeMap={treeMap}
|
treeMap={treeMap}
|
||||||
targetSlot={null}
|
|
||||||
app={app}
|
app={app}
|
||||||
componentWrapper={componentWrapper}
|
componentWrapper={componentWrapper}
|
||||||
gridCallbacks={gridCallbacks}
|
gridCallbacks={gridCallbacks}
|
||||||
|
@ -16,7 +16,6 @@ type ApplicationTrait = ArrayElement<RuntimeApplicationComponent['traits']>;
|
|||||||
const _ImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>((props, ref) => {
|
const _ImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>((props, ref) => {
|
||||||
const {
|
const {
|
||||||
component: c,
|
component: c,
|
||||||
targetSlot,
|
|
||||||
app,
|
app,
|
||||||
children,
|
children,
|
||||||
componentWrapper: ComponentWrapper,
|
componentWrapper: ComponentWrapper,
|
||||||
@ -153,15 +152,13 @@ const _ImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>((props,
|
|||||||
}, [c.properties, stateManager]);
|
}, [c.properties, stateManager]);
|
||||||
|
|
||||||
const mergedProps = { ...evaledComponentProperties, ...propsFromTraits };
|
const mergedProps = { ...evaledComponentProperties, ...propsFromTraits };
|
||||||
const { slotsMap, ...restProps } = props;
|
|
||||||
const Slot = genSlots(props);
|
const Slot = genSlots(props);
|
||||||
const C = unmount ? null : (
|
const C = unmount ? null : (
|
||||||
<Impl
|
<Impl
|
||||||
key={c.id}
|
key={c.id}
|
||||||
|
{...props}
|
||||||
{...mergedProps}
|
{...mergedProps}
|
||||||
{...restProps}
|
|
||||||
Slot={Slot}
|
Slot={Slot}
|
||||||
slotsMap={slotsMap}
|
|
||||||
mergeState={mergeState}
|
mergeState={mergeState}
|
||||||
subscribeMethods={subscribeMethods}
|
subscribeMethods={subscribeMethods}
|
||||||
/>
|
/>
|
||||||
@ -175,8 +172,11 @@ const _ImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>((props,
|
|||||||
);
|
);
|
||||||
|
|
||||||
let parentComponent;
|
let parentComponent;
|
||||||
if (targetSlot && app) {
|
|
||||||
parentComponent = app.spec.components.find(c => c.id === targetSlot.id);
|
const slotTrait = c.traits.find(t => t.type === 'core/v1/slot')
|
||||||
|
|
||||||
|
if (slotTrait && app) {
|
||||||
|
parentComponent = app.spec.components.find(c => c.id === (slotTrait.properties.container as any).id);
|
||||||
}
|
}
|
||||||
// wrap component, but grid_layout is root component and cannot be chosen, so don't wrap it
|
// wrap component, but grid_layout is root component and cannot be chosen, so don't wrap it
|
||||||
if (
|
if (
|
||||||
@ -197,9 +197,7 @@ const _ImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>((props,
|
|||||||
const {
|
const {
|
||||||
component,
|
component,
|
||||||
services,
|
services,
|
||||||
targetSlot,
|
|
||||||
app,
|
app,
|
||||||
slotsMap,
|
|
||||||
componentWrapper,
|
componentWrapper,
|
||||||
gridCallbacks,
|
gridCallbacks,
|
||||||
...restProps
|
...restProps
|
||||||
|
@ -9,7 +9,6 @@ import {
|
|||||||
RuntimeApplicationComponent,
|
RuntimeApplicationComponent,
|
||||||
} from '../../types/RuntimeSchema';
|
} from '../../types/RuntimeSchema';
|
||||||
import { EventHandlerSchema } from '../../types/TraitPropertiesSchema';
|
import { EventHandlerSchema } from '../../types/TraitPropertiesSchema';
|
||||||
import { resolveAppComponents } from '../../services/resolveAppComponents';
|
|
||||||
import { ImplWrapper } from './ImplWrapper';
|
import { ImplWrapper } from './ImplWrapper';
|
||||||
import { watch } from '../../utils/watchReactivity';
|
import { watch } from '../../utils/watchReactivity';
|
||||||
import { ImplementedRuntimeModule } from '../../services/registry';
|
import { ImplementedRuntimeModule } from '../../services/registry';
|
||||||
@ -149,23 +148,12 @@ const ModuleRendererContent: React.FC<Props & { moduleSpec: ImplementedRuntimeMo
|
|||||||
}, [evaledHanlders, moduleId, services.apiService]);
|
}, [evaledHanlders, moduleId, services.apiService]);
|
||||||
|
|
||||||
const result = useMemo(() => {
|
const result = useMemo(() => {
|
||||||
const { topLevelComponents, slotComponentsMap } = resolveAppComponents(
|
const { treeMap, topLevelComponents } = resolveTreeMap(evaledModuleTemplate);
|
||||||
evaledModuleTemplate,
|
|
||||||
{
|
|
||||||
services,
|
|
||||||
app,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const {treeMap} = resolveTreeMap(evaledModuleTemplate)
|
|
||||||
return topLevelComponents.map(c => {
|
return topLevelComponents.map(c => {
|
||||||
const slotsMap = slotComponentsMap.get(c.id);
|
|
||||||
return (
|
return (
|
||||||
<ImplWrapper
|
<ImplWrapper
|
||||||
key={c.id}
|
key={c.id}
|
||||||
component={c}
|
component={c}
|
||||||
slotsMap={slotsMap}
|
|
||||||
Slot={() => null}
|
|
||||||
targetSlot={null}
|
|
||||||
services={services}
|
services={services}
|
||||||
app={app}
|
app={app}
|
||||||
treeMap={treeMap}
|
treeMap={treeMap}
|
||||||
@ -176,7 +164,6 @@ const ModuleRendererContent: React.FC<Props & { moduleSpec: ImplementedRuntimeMo
|
|||||||
|
|
||||||
return <>{result}</>;
|
return <>{result}</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function parseTypeComponents(
|
function parseTypeComponents(
|
||||||
c: Application['spec']['components'][0]
|
c: Application['spec']['components'][0]
|
||||||
|
@ -17,15 +17,7 @@ export function genSlots<K extends string>(
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{childrenSchema.map(c => {
|
{childrenSchema.map(c => {
|
||||||
return (
|
return <ImplWrapper key={c.id} {...props} component={c} />;
|
||||||
<ImplWrapper
|
|
||||||
Slot={() => null}
|
|
||||||
targetSlot={null}
|
|
||||||
key={c.id}
|
|
||||||
{...props}
|
|
||||||
component={c}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -41,14 +33,6 @@ export function genSlotsAsArray<K extends string>(
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return childrenSchema.map(c => {
|
return childrenSchema.map(c => {
|
||||||
return () => (
|
return () => <ImplWrapper key={c.id} {...props} component={c} />;
|
||||||
<ImplWrapper
|
|
||||||
Slot={() => null}
|
|
||||||
targetSlot={null}
|
|
||||||
key={c.id}
|
|
||||||
{...props}
|
|
||||||
component={c}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,12 @@ import {
|
|||||||
RouterCtx,
|
RouterCtx,
|
||||||
useNavigate,
|
useNavigate,
|
||||||
} from './hooks';
|
} from './hooks';
|
||||||
import { SlotsMap } from '../../../types/RuntimeSchema';
|
import {
|
||||||
|
RuntimeApplicationComponent,
|
||||||
|
UIServices,
|
||||||
|
TreeMap,
|
||||||
|
} from '../../../types/RuntimeSchema';
|
||||||
|
import { genSlotsAsArray } from '../../../components/_internal/Slot';
|
||||||
|
|
||||||
export type RouteLikeElement = PropsWithChildren<{
|
export type RouteLikeElement = PropsWithChildren<{
|
||||||
path?: string;
|
path?: string;
|
||||||
@ -51,7 +56,7 @@ export const Route: React.FC<RouteProps> = ({ match, children, mergeState }) =>
|
|||||||
}
|
}
|
||||||
mergeState(destroyObj);
|
mergeState(destroyObj);
|
||||||
};
|
};
|
||||||
}, [params]);
|
}, [matches, mergeState, params]);
|
||||||
if (!matches) return null;
|
if (!matches) return null;
|
||||||
return typeof children === 'function' ? children(params) : children;
|
return typeof children === 'function' ? children(params) : children;
|
||||||
};
|
};
|
||||||
@ -59,18 +64,15 @@ export const Route: React.FC<RouteProps> = ({ match, children, mergeState }) =>
|
|||||||
type SwitchProps = {
|
type SwitchProps = {
|
||||||
location?: string;
|
location?: string;
|
||||||
switchPolicy: SwitchPolicy;
|
switchPolicy: SwitchPolicy;
|
||||||
slotMap?: SlotsMap<string>;
|
component: RuntimeApplicationComponent;
|
||||||
|
treeMap: TreeMap<string>;
|
||||||
|
services: UIServices;
|
||||||
mergeState: (partialState: any) => void;
|
mergeState: (partialState: any) => void;
|
||||||
subscribeMethods: (map: { [key: string]: (parameters: any) => void }) => void;
|
subscribeMethods: (map: { [key: string]: (parameters: any) => void }) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Switch: React.FC<SwitchProps> = ({
|
export const Switch: React.FC<SwitchProps> = props => {
|
||||||
switchPolicy,
|
const { switchPolicy, location, mergeState, subscribeMethods } = props;
|
||||||
location,
|
|
||||||
slotMap,
|
|
||||||
mergeState,
|
|
||||||
subscribeMethods,
|
|
||||||
}) => {
|
|
||||||
const [originalLocation] = useLocation();
|
const [originalLocation] = useLocation();
|
||||||
const matcher = useMemo(() => makeMatcher(), []);
|
const matcher = useMemo(() => makeMatcher(), []);
|
||||||
|
|
||||||
@ -80,7 +82,7 @@ export const Switch: React.FC<SwitchProps> = ({
|
|||||||
let defaultPath: string | undefined = undefined;
|
let defaultPath: string | undefined = undefined;
|
||||||
const result = switchPolicy.map(
|
const result = switchPolicy.map(
|
||||||
({ type, path, slotId, href, default: _default, exact, strict, sensitive }) => {
|
({ type, path, slotId, href, default: _default, exact, strict, sensitive }) => {
|
||||||
const componentsArr = slotMap && slotMap.get(slotId);
|
const componentsArr = genSlotsAsArray(props, slotId);
|
||||||
if (defaultPath === undefined && _default) {
|
if (defaultPath === undefined && _default) {
|
||||||
defaultPath = path;
|
defaultPath = path;
|
||||||
}
|
}
|
||||||
@ -106,7 +108,7 @@ export const Switch: React.FC<SwitchProps> = ({
|
|||||||
if (componentsArr.length !== 1) {
|
if (componentsArr.length !== 1) {
|
||||||
console.warn('router slot can only have one component');
|
console.warn('router slot can only have one component');
|
||||||
}
|
}
|
||||||
const { component: C } = componentsArr[0];
|
const C = componentsArr[0];
|
||||||
if (C.displayName === 'router') {
|
if (C.displayName === 'router') {
|
||||||
return (
|
return (
|
||||||
// it should match both itself and its children path
|
// it should match both itself and its children path
|
||||||
@ -141,7 +143,7 @@ export const Switch: React.FC<SwitchProps> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}, [switchPolicy]);
|
}, [mergeState, props, switchPolicy]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
subscribeMethods({
|
subscribeMethods({
|
||||||
@ -149,7 +151,7 @@ export const Switch: React.FC<SwitchProps> = ({
|
|||||||
naviagte(path);
|
naviagte(path);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}, []);
|
}, [naviagte, subscribeMethods]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// to assign location as a state
|
// to assign location as a state
|
||||||
@ -161,7 +163,7 @@ export const Switch: React.FC<SwitchProps> = ({
|
|||||||
route: undefined,
|
route: undefined,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}, [loc]);
|
}, [loc, mergeState]);
|
||||||
|
|
||||||
for (const element of flattenChildren(routes)) {
|
for (const element of flattenChildren(routes)) {
|
||||||
const match: Match<DefaultParams> = element.props.path
|
const match: Match<DefaultParams> = element.props.path
|
||||||
@ -228,7 +230,7 @@ export const Redirect: React.FC<RedirectProps> = props => {
|
|||||||
// empty array means running the effect once, navRef is a ref so it never changes
|
// empty array means running the effect once, navRef is a ref so it never changes
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
navRef.current!();
|
navRef.current!();
|
||||||
}, []);
|
}, [navRef]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
@ -59,13 +59,10 @@ export default implementRuntimeComponent({
|
|||||||
styleSlots: [],
|
styleSlots: [],
|
||||||
events: [],
|
events: [],
|
||||||
},
|
},
|
||||||
})(({ slotsMap, switchPolicy, subscribeMethods, mergeState }) => {
|
})((props) => {
|
||||||
return (
|
return (
|
||||||
<Switch
|
<Switch
|
||||||
slotMap={slotsMap}
|
{...props}
|
||||||
switchPolicy={switchPolicy}
|
|
||||||
subscribeMethods={subscribeMethods}
|
|
||||||
mergeState={mergeState}
|
|
||||||
></Switch>
|
></Switch>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { RuntimeApplication } from '@sunmao-ui/core';
|
|
||||||
import { ContainerPropertySchema } from '../traits/core/slot';
|
|
||||||
import { Static } from '@sinclair/typebox';
|
|
||||||
import {
|
|
||||||
ComponentParamsFromApp,
|
|
||||||
UIServices,
|
|
||||||
SlotComponentMap,
|
|
||||||
} from '../types/RuntimeSchema';
|
|
||||||
import { ImplWrapper } from '../components/_internal/ImplWrapper';
|
|
||||||
|
|
||||||
export function resolveAppComponents(
|
|
||||||
components: RuntimeApplication['spec']['components'],
|
|
||||||
params: {
|
|
||||||
services: UIServices;
|
|
||||||
app?: RuntimeApplication;
|
|
||||||
} & ComponentParamsFromApp
|
|
||||||
): {
|
|
||||||
topLevelComponents: RuntimeApplication['spec']['components'];
|
|
||||||
slotComponentsMap: SlotComponentMap;
|
|
||||||
} {
|
|
||||||
const topLevelComponents: RuntimeApplication['spec']['components'] = [];
|
|
||||||
const slotComponentsMap: SlotComponentMap = new Map();
|
|
||||||
|
|
||||||
for (const c of components) {
|
|
||||||
// handle component with slot trait
|
|
||||||
const slotTrait = c.traits.find(t => t.parsedType.name === 'slot');
|
|
||||||
if (slotTrait) {
|
|
||||||
const { id, slot } = (
|
|
||||||
slotTrait.properties as {
|
|
||||||
container: Static<typeof ContainerPropertySchema>;
|
|
||||||
}
|
|
||||||
).container;
|
|
||||||
if (!slotComponentsMap.has(id)) {
|
|
||||||
slotComponentsMap.set(id, new Map());
|
|
||||||
}
|
|
||||||
if (!slotComponentsMap.get(id)?.has(slot)) {
|
|
||||||
slotComponentsMap.get(id)?.set(slot, []);
|
|
||||||
}
|
|
||||||
const component = React.forwardRef<HTMLDivElement, any>((props, ref) => (
|
|
||||||
<ImplWrapper
|
|
||||||
component={c}
|
|
||||||
slotsMap={slotComponentsMap.get(c.id)}
|
|
||||||
targetSlot={{ id, slot }}
|
|
||||||
{...params}
|
|
||||||
{...props}
|
|
||||||
ref={ref}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
component.displayName = c.parsedType.name;
|
|
||||||
slotComponentsMap.get(id)?.get(slot)?.push({
|
|
||||||
component,
|
|
||||||
id: c.id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the component is neither assigned with slot trait nor route trait, consider it as a top level component
|
|
||||||
!slotTrait && topLevelComponents.push(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
topLevelComponents,
|
|
||||||
slotComponentsMap,
|
|
||||||
};
|
|
||||||
}
|
|
@ -44,11 +44,7 @@ export type AppProps = {
|
|||||||
// TODO: (type-safe), remove fallback type
|
// TODO: (type-safe), remove fallback type
|
||||||
export type ImplWrapperProps<KSlot extends string = string> = {
|
export type ImplWrapperProps<KSlot extends string = string> = {
|
||||||
component: RuntimeApplicationComponent;
|
component: RuntimeApplicationComponent;
|
||||||
// TODO: (type-safe), remove slotsMap from props
|
|
||||||
slotsMap: SlotsMap<KSlot> | undefined;
|
|
||||||
treeMap: TreeMap<KSlot>;
|
treeMap: TreeMap<KSlot>;
|
||||||
Slot: SlotType<KSlot>;
|
|
||||||
targetSlot: { id: string; slot: string } | null;
|
|
||||||
services: UIServices;
|
services: UIServices;
|
||||||
app?: RuntimeApplication;
|
app?: RuntimeApplication;
|
||||||
} & ComponentParamsFromApp;
|
} & ComponentParamsFromApp;
|
||||||
@ -58,15 +54,6 @@ export type TreeMap<KSlot extends string> = Record<
|
|||||||
Record<KSlot, RuntimeApplicationComponent[]>
|
Record<KSlot, RuntimeApplicationComponent[]>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type SlotComponentMap = Map<string, SlotsMap<string>>;
|
|
||||||
export type SlotsMap<K extends string> = Map<
|
|
||||||
K,
|
|
||||||
Array<{
|
|
||||||
component: React.FC;
|
|
||||||
id: string;
|
|
||||||
}>
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type CallbackMap<K extends string> = Record<K, () => void>;
|
export type CallbackMap<K extends string> = Record<K, () => void>;
|
||||||
|
|
||||||
export type SubscribeMethods<U> = (map: {
|
export type SubscribeMethods<U> = (map: {
|
||||||
@ -87,7 +74,9 @@ export type ComponentImplementationProps<
|
|||||||
KEvent extends string
|
KEvent extends string
|
||||||
> = ImplWrapperProps<KSlot> &
|
> = ImplWrapperProps<KSlot> &
|
||||||
TraitResult<KStyleSlot, KEvent>['props'] &
|
TraitResult<KStyleSlot, KEvent>['props'] &
|
||||||
RuntimeFunctions<TState, TMethods>;
|
RuntimeFunctions<TState, TMethods> & {
|
||||||
|
Slot: SlotType<KSlot>;
|
||||||
|
};
|
||||||
|
|
||||||
export type TraitResult<KStyleSlot extends string, KEvent extends string> = {
|
export type TraitResult<KStyleSlot extends string, KEvent extends string> = {
|
||||||
props: {
|
props: {
|
||||||
|
Loading…
Reference in New Issue
Block a user