update chakra-ui-lib slot

This commit is contained in:
Bowen Tan 2021-12-31 10:54:19 +08:00
parent cca2930a2c
commit b698e1e5d2
14 changed files with 86 additions and 96 deletions

View File

@ -1,6 +1,6 @@
import { Type } from '@sinclair/typebox';
import { Box as BaseBox } from '@chakra-ui/react';
import { implementRuntimeComponent2, Slot, GRID_HEIGHT } from '@sunmao-ui/runtime';
import { implementRuntimeComponent2, GRID_HEIGHT } from '@sunmao-ui/runtime';
import { pick } from 'lodash-es';
import { css } from '@emotion/css';
@ -292,8 +292,9 @@ export default implementRuntimeComponent2({
styleSlots: ['content'],
events: [],
},
})(({ slotsMap, customStyle, ...restProps }) => {
})(({ slotsMap, customStyle, Slot, ...restProps }) => {
const styleProps = pick(restProps, StyleProps);
console.log('slotsMap', slotsMap)
return (
<BaseBox
width="full"
@ -307,7 +308,7 @@ export default implementRuntimeComponent2({
${customStyle?.content}
`}
>
<Slot slotsMap={slotsMap} slot="content" />
<Slot slot="content" />
</BaseBox>
);
});

View File

@ -1,7 +1,7 @@
import { useState, useEffect } from 'react';
import { Type } from '@sinclair/typebox';
import { CheckboxGroup as BaseCheckboxGroup } from '@chakra-ui/react';
import { implementRuntimeComponent2, Slot } from '@sunmao-ui/runtime';
import { implementRuntimeComponent2 } from '@sunmao-ui/runtime';
import { SizePropertySchema, IsDisabledSchema } from './Checkbox';
const DefaultValueSchema = Type.Array(Type.Union([Type.String(), Type.Number()]));
@ -37,7 +37,7 @@ export default implementRuntimeComponent2({
styleSlots: [],
events: [],
},
})(({ size, defaultValue, isDisabled, slotsMap, mergeState }) => {
})(({ size, defaultValue, isDisabled, Slot, mergeState }) => {
const [value, setValue] = useState(defaultValue);
useEffect(() => {
mergeState({ value });
@ -50,7 +50,7 @@ export default implementRuntimeComponent2({
isDisabled={isDisabled}
onChange={val => setValue(val)}
>
<Slot slotsMap={slotsMap} slot="content" />
<Slot slot="content" />
</BaseCheckboxGroup>
);
});

View File

@ -1,7 +1,6 @@
import { useEffect, useState, useRef } from 'react';
import {
implementRuntimeComponent2,
Slot,
DIALOG_CONTAINER_ID,
} from '@sunmao-ui/runtime';
import {
@ -62,7 +61,7 @@ export default implementRuntimeComponent2({
},
})(
({
slotsMap,
Slot,
subscribeMethods,
callbackMap: callbacks,
title: customerTitle,
@ -133,7 +132,7 @@ export default implementRuntimeComponent2({
>
<AlertDialogHeader>{title}</AlertDialogHeader>
<AlertDialogBody>
<Slot slotsMap={slotsMap} slot="content" />
<Slot slot="content" />
</AlertDialogBody>
<AlertDialogFooter>

View File

@ -1,7 +1,7 @@
import { css } from '@emotion/css';
import { Type } from '@sinclair/typebox';
import { HStack as BaseHStack } from '@chakra-ui/react';
import { implementRuntimeComponent2, Slot } from '@sunmao-ui/runtime';
import { implementRuntimeComponent2 } from '@sunmao-ui/runtime';
import {
DirectionSchema,
FlexWrapSchema,
@ -39,7 +39,7 @@ export default implementRuntimeComponent2({
methods: {},
events: [],
},
})(({ direction, wrap, align, justify, spacing, slotsMap, customStyle }) => {
})(({ direction, wrap, align, justify, spacing, Slot, customStyle }) => {
return (
<BaseHStack
height="full"
@ -54,7 +54,7 @@ export default implementRuntimeComponent2({
`}
{...{ direction, wrap, align, justify, spacing }}
>
<Slot slotsMap={slotsMap} slot="content" />
<Slot slot="content" />
</BaseHStack>
);
});

View File

@ -1,7 +1,7 @@
import { useState, useEffect } from 'react';
import { Type } from '@sinclair/typebox';
import { RadioGroup as BaseRadioGroup } from '@chakra-ui/react';
import { implementRuntimeComponent2, Slot } from '@sunmao-ui/runtime';
import { implementRuntimeComponent2 } from '@sunmao-ui/runtime';
import { css } from '@emotion/css';
const StateSchema = Type.Object({
@ -35,7 +35,7 @@ export default implementRuntimeComponent2({
styleSlots: ['content'],
events: [],
},
})(({ defaultValue, isNumerical, slotsMap, mergeState, customStyle }) => {
})(({ defaultValue, isNumerical, Slot, mergeState, customStyle }) => {
const [value, setValue] = useState(defaultValue);
useEffect(() => {
@ -54,7 +54,7 @@ export default implementRuntimeComponent2({
${customStyle?.content}
`}
>
<Slot slotsMap={slotsMap} slot="content" />
<Slot slot="content" />
</BaseRadioGroup>
);
});

View File

@ -1,6 +1,6 @@
import { ChakraProvider, extendTheme } from '@chakra-ui/react';
import { Type } from '@sinclair/typebox';
import { implementRuntimeComponent2, Slot } from '@sunmao-ui/runtime';
import { implementRuntimeComponent2 } from '@sunmao-ui/runtime';
export default implementRuntimeComponent2({
version: 'chakra_ui/v1',
@ -21,7 +21,7 @@ export default implementRuntimeComponent2({
styleSlots: [],
events: [],
},
})(({ slotsMap }) => {
})(({ Slot }) => {
return (
<ChakraProvider
theme={extendTheme({
@ -29,7 +29,7 @@ export default implementRuntimeComponent2({
useSystemColorMode: false,
})}
>
<Slot slotsMap={slotsMap} slot="root" />
<Slot slot="root" />
</ChakraProvider>
);
});

View File

@ -1,6 +1,6 @@
import { Type } from '@sinclair/typebox';
import { Stack as BaseStack } from '@chakra-ui/react';
import { implementRuntimeComponent2, Slot } from '@sunmao-ui/runtime';
import { implementRuntimeComponent2 } from '@sunmao-ui/runtime';
export const DirectionSchema = Type.Optional(
Type.Union([
@ -67,10 +67,10 @@ export default implementRuntimeComponent2({
styleSlots: [],
events: [],
},
})(({ direction, wrap, align, justify, spacing, slotsMap }) => {
})(({ direction, wrap, align, justify, spacing, Slot }) => {
return (
<BaseStack {...{ direction, wrap, align, justify, spacing }}>
<Slot slotsMap={slotsMap} slot="content" />
<Slot slot="content" />
</BaseStack>
);
});

View File

@ -1,6 +1,6 @@
import { Type } from '@sinclair/typebox';
import { Tooltip } from '@chakra-ui/react';
import { implementRuntimeComponent2, Slot, TextPropertySchema } from '@sunmao-ui/runtime';
import { implementRuntimeComponent2, TextPropertySchema } from '@sunmao-ui/runtime';
import { ColorSchemePropertySchema } from './Types/ColorScheme';
const PropsSchema = Type.Object({
@ -64,7 +64,7 @@ export default implementRuntimeComponent2({
hasArrow,
isDisabled,
defaultIsOpen,
slotsMap,
Slot,
}) => {
return (
/*
@ -80,7 +80,7 @@ export default implementRuntimeComponent2({
defaultIsOpen={defaultIsOpen}
shouldWrapChildren={shouldWrapChildren}
>
<Slot slotsMap={slotsMap} slot="content" />
<Slot slot="content" />
</Tooltip>
);
}

View File

@ -1,7 +1,7 @@
import { css } from '@emotion/css';
import { Type } from '@sinclair/typebox';
import { VStack as BaseVStack } from '@chakra-ui/react';
import { implementRuntimeComponent2, Slot } from '@sunmao-ui/runtime';
import { implementRuntimeComponent2 } from '@sunmao-ui/runtime';
import {
DirectionSchema,
FlexWrapSchema,
@ -45,7 +45,7 @@ export default implementRuntimeComponent2({
align,
justify,
spacing,
slotsMap,
Slot,
customStyle,
}) => {
return (
@ -62,7 +62,7 @@ export default implementRuntimeComponent2({
`}
{...{ direction, wrap, align, justify, spacing }}
>
<Slot slotsMap={slotsMap} slot="content" />
<Slot slot="content" />
</BaseVStack>
);
})

View File

@ -5,7 +5,7 @@ import { ImplWrapper } from './services/ImplWrapper';
import { resolveAppComponents } from './services/resolveAppComponents';
import { AppProps, UIServices } from './types/RuntimeSchema';
import { DebugEvent, DebugStore } from './services/DebugComponents';
import { getSlotWithMap } from 'src/components/_internal/Slot';
import { getSlotWithMap } from './components/_internal/Slot';
// inject modules to App
export function genApp(services: UIServices) {
@ -37,12 +37,12 @@ export const App: React.FC<AppProps> = props => {
}),
[app, componentWrapper, gridCallbacks, services]
);
return (
<div className="App" style={{ height: '100vh', overflow: 'auto' }}>
{topLevelComponents.map(c => {
const slotsMap = slotComponentsMap.get(c.id);
const Slot = getSlotWithMap(slotsMap);
console.log('slotsMapslotsMapslotsMap', slotsMap)
return (
<ImplWrapper
key={c.id}

View File

@ -6,7 +6,7 @@ import {
ImplWrapperProps,
TraitResult,
} from '../types/RuntimeSchema';
import { getSlotWithMap } from 'src/components/_internal/Slot';
import { getSlotWithMap } from '../components/_internal/Slot';
type ArrayElement<ArrayType extends readonly unknown[]> =
ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
@ -57,34 +57,39 @@ export const ImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>(
},
[c.id, stateManager.store]
);
const subscribeMethods = useCallback((map: any) => {
handlerMap.current = { ...handlerMap, ...map };
globalHandlerMap.set(c.id, handlerMap.current);
}, [c.id, globalHandlerMap]);
const subscribeMethods = useCallback(
(map: any) => {
handlerMap.current = { ...handlerMap, ...map };
globalHandlerMap.set(c.id, handlerMap.current);
},
[c.id, globalHandlerMap]
);
const excecuteTrait = useCallback((
trait: ApplicationTrait,
traitProperty: ApplicationTrait['properties']
) => {
const tImpl = registry.getTrait(
trait.parsedType.version,
trait.parsedType.name
).impl;
return tImpl({
...traitProperty,
componentId: c.id,
mergeState,
subscribeMethods,
services,
});
}, [c.id, mergeState, registry, services, subscribeMethods])
const excecuteTrait = useCallback(
(trait: ApplicationTrait, traitProperty: ApplicationTrait['properties']) => {
const tImpl = registry.getTrait(
trait.parsedType.version,
trait.parsedType.name
).impl;
return tImpl({
...traitProperty,
componentId: c.id,
mergeState,
subscribeMethods,
services,
});
},
[c.id, mergeState, registry, services, subscribeMethods]
);
// result returned from traits
const [traitResults, setTraitResults] = useState<TraitResult<string, string>[]>(() => {
return c.traits.map(trait =>
excecuteTrait(trait, stateManager.deepEval(trait.properties).result)
);
});
const [traitResults, setTraitResults] = useState<TraitResult<string, string>[]>(
() => {
return c.traits.map(trait =>
excecuteTrait(trait, stateManager.deepEval(trait.properties).result)
);
}
);
// eval traits' properties then excecute traits
useEffect(() => {
@ -153,13 +158,13 @@ export const ImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>(
const mergedProps = { ...evaledComponentProperties, ...propsFromTraits };
const { slotsMap, ...restProps } = props;
const Slot = getSlotWithMap(slotsMap);
const C = unmount ? null : (
<Impl
key={c.id}
{...mergedProps}
{...restProps}
Slot={Slot}
slotsMap={slotsMap}
mergeState={mergeState}
subscribeMethods={subscribeMethods}
/>

View File

@ -1,12 +1,11 @@
import {
RuntimeComponentSpec,
RuntimeTraitSpec,
RuntimeModuleSpec,
ApplicationComponent,
} from '@sunmao-ui/core';
// components
/* --- plain --- */
// import PlainButton from '../components/plain/Button';
import PlainButton from '../components/plain/Button';
import CoreText from '../components/core/Text';
import CoreGridLayout from '../components/core/GridLayout';
import CoreRouter from '../components/core/Router';
@ -29,7 +28,7 @@ import {
import { parseType } from '../utils/parseType';
import { parseModuleSchema } from '../utils/parseModuleSchema';
import { cloneDeep } from 'lodash-es';
import { ImplementedRuntimeComponent2 } from '../utils/buildKit';
import { ImplementedRuntimeComponent } from '../utils/buildKit';
export type ComponentImplementation<
TProps = any,
@ -42,10 +41,6 @@ export type ComponentImplementation<
TProps & ComponentImplementationProps<TState, TMethods, KSlot, KStyleSlot, KEvent>
>;
export type ImplementedRuntimeComponent = RuntimeComponentSpec & {
impl: ComponentImplementation;
};
export type ImplementedRuntimeTrait = RuntimeTraitSpec & {
impl: TraitImplementation;
};
@ -55,17 +50,24 @@ export type ImplementedRuntimeModule = RuntimeModuleSpec & {
};
export type SunmaoLib = {
components?: ImplementedRuntimeComponent2<string, string, string, string>[];
components?: ImplementedRuntimeComponent<string, string, string, string>[];
traits?: ImplementedRuntimeTrait[];
modules?: ImplementedRuntimeModule[];
};
type AnyImplementedRuntimeComponent = ImplementedRuntimeComponent<
string,
string,
string,
string
>;
export class Registry {
components = new Map<string, Map<string, any>>();
components = new Map<string, Map<string, AnyImplementedRuntimeComponent>>();
traits = new Map<string, Map<string, ImplementedRuntimeTrait>>();
modules = new Map<string, Map<string, ImplementedRuntimeModule>>();
registerComponent(c: ImplementedRuntimeComponent) {
registerComponent(c: AnyImplementedRuntimeComponent) {
if (this.components.get(c.version)?.has(c.metadata.name)) {
throw new Error(
`Already has component ${c.version}/${c.metadata.name} in this registry.`
@ -77,24 +79,7 @@ export class Registry {
this.components.get(c.version)?.set(c.metadata.name, c);
}
registerComponent2<
KMethodName extends string,
KStyleSlot extends string,
KSlot extends string,
KEvent extends string
>(c: ImplementedRuntimeComponent2<KMethodName, KStyleSlot, KSlot, KEvent>) {
if (this.components.get(c.version)?.has(c.metadata.name)) {
throw new Error(
`Already has component ${c.version}/${c.metadata.name} in this registry.`
);
}
if (!this.components.has(c.version)) {
this.components.set(c.version, new Map());
}
this.components.get(c.version)?.set(c.metadata.name, c);
}
getComponent(version: string, name: string): ImplementedRuntimeComponent {
getComponent(version: string, name: string): AnyImplementedRuntimeComponent {
const c = this.components.get(version)?.get(name);
if (!c) {
throw new Error(`Component ${version}/${name} has not registered yet.`);
@ -102,13 +87,13 @@ export class Registry {
return c;
}
getComponentByType(type: string): ImplementedRuntimeComponent {
getComponentByType(type: string): AnyImplementedRuntimeComponent {
const { version, name } = parseType(type);
return this.getComponent(version, name);
}
getAllComponents(): ImplementedRuntimeComponent[] {
const res: ImplementedRuntimeComponent[] = [];
getAllComponents(): AnyImplementedRuntimeComponent[] {
const res: AnyImplementedRuntimeComponent[] = [];
for (const version of this.components.values()) {
for (const component of version.values()) {
res.push(component);
@ -198,12 +183,12 @@ export class Registry {
export function initRegistry(): Registry {
const registry = new Registry();
// TODO: (type-safe) register v2 component
// registry.registerComponent(PlainButton);
registry.registerComponent2(CoreText);
registry.registerComponent2(CoreGridLayout);
registry.registerComponent2(CoreRouter);
registry.registerComponent2(CoreDummy);
registry.registerComponent2(CoreModuleContainer);
registry.registerComponent(PlainButton);
registry.registerComponent(CoreText);
registry.registerComponent(CoreGridLayout);
registry.registerComponent(CoreRouter);
registry.registerComponent(CoreDummy);
registry.registerComponent(CoreModuleContainer);
registry.registerTrait(CoreState);
registry.registerTrait(CoreArrayState);

View File

@ -6,7 +6,7 @@ import { StateManager } from '../services/stateStore';
import { Application, RuntimeApplication } from '@sunmao-ui/core';
import { EventHandlerSchema } from './TraitPropertiesSchema';
import { Type } from '@sinclair/typebox';
import { SlotType } from 'src/components/_internal/Slot';
import { SlotType } from '../components/_internal/Slot';
export type RuntimeApplicationComponent = RuntimeApplication['spec']['components'][0];

View File

@ -6,7 +6,7 @@ import {
} from '@sunmao-ui/core';
import { ComponentImplementation } from '../services/registry';
export type ImplementedRuntimeComponent2<
export type ImplementedRuntimeComponent<
KMethodName extends string,
KStyleSlot extends string,
KSlot extends string,
@ -38,7 +38,7 @@ export function implementRuntimeComponent2<
ToStringUnion<T['spec']['styleSlots']>,
ToStringUnion<T['spec']['events']>
>
) => ImplementedRuntimeComponent2<KMethodName, KStyleSlot, KSlot, KEvent> {
) => ImplementedRuntimeComponent<KMethodName, KStyleSlot, KSlot, KEvent> {
return impl => ({
...createComponent2(options),
impl,