Skip to content

Commit

Permalink
Merge pull request codebdy#85 from rxdrag/next
Browse files Browse the repository at this point in the history
Next
  • Loading branch information
codebdy authored Feb 19, 2023
2 parents e7471e8 + 4127a39 commit b2fe944
Show file tree
Hide file tree
Showing 181 changed files with 6,639 additions and 1,385 deletions.
6 changes: 5 additions & 1 deletion note.MD
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Reaction editor,Reaction的svg图标如果有多个path,那么每个path要加key

Context 下发 reaction,能保证列表里的控件能拿到唯一id的reaction
Context 下发 reaction,能保证列表里的控件能拿到唯一id的reaction

可以进一步简化属性面板的schema,现在的还是太罗嗦 OK

一个组件可以由多个部分组成,比如表格列由列头单元格跟body单元格组合而成,需要修改core以及plugin相关
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const ComponentDesignerView = memo((props: { nodeId: string }) => {
return <Component ref={!behavior?.isNoRef() ? handleRef : undefined} {...realProps} >
<Locked node={node}>
{
node.children?.map((childId: string) => {
!node.meta?.selfRender && node.children?.map((childId: string) => {
return <ComponentDesignerView key={childId} nodeId={childId} />;
})
}
Expand Down
25 changes: 17 additions & 8 deletions src/core-react/DesignRoot.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import { useCallback, useMemo, useState } from "react"
import { DesignComponentsContext, IComponentsParams } from "./contexts"
import { DesignComponentsContext, IDesignerComponentsParams } from "./contexts"
import { IComponents } from "./interfaces"

export const DesignRoot = (props: {
components?: IComponents
children: React.ReactNode
components?: IComponents,
tools?: IComponents,
children: React.ReactNode,
}) => {
const { components: initalComponents, children } = props
const { components: initialComponents, tools: initialTools, children } = props
const [components, setComponents] = useState<IComponents>({})
const [tools, setTools] = useState<IComponents>({})
const handleRegister = useCallback((...components: IComponents[]) => {
for (const com of components) {
setComponents(coms => ({ ...coms, ...com }))
}
}, [])

const params: IComponentsParams = useMemo(() => {
const handleRegisterTools = useCallback((...components: IComponents[]) => {
for (const com of components) {
setTools(coms => ({ ...coms, ...com }))
}
}, [])
const params: IDesignerComponentsParams = useMemo(() => {
return {
components: { ...initalComponents, ...components },
registerComponents: handleRegister
components: { ...initialComponents, ...components },
tools: { ...initialTools, ...tools },
registerComponents: handleRegister,
registerTools: handleRegisterTools,
}
}, [components, handleRegister, initalComponents])
}, [components, handleRegister, handleRegisterTools, initialComponents, initialTools, tools])

return (
<DesignComponentsContext.Provider value={params}>
Expand Down
4 changes: 2 additions & 2 deletions src/core-react/canvas/IframeCanvas/index_old.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ReactDOM from 'react-dom/client';
import { useDesignerEngine } from "core-react/hooks";
import { CanvasRender } from "../CanvasRender"
import { IDocument } from "core/interfaces";
import { useDesignComponents } from "core-react/hooks/useDesignComponents";
import { useDesignComponentsParams } from "core-react/hooks/useDesignComponentsParams";
import { IFrameCanvasImpl } from "core/shell/IFrameCanvasImpl";
import { CanvasResizeDriver, CanvasScrollDriver, DragDropDriver, MouseClickDriver, MouseMoveDriver } from "core/shell/drivers";
import { MouseOverOutDriver } from "core/shell/drivers/MouseOverOutDriver";
Expand Down Expand Up @@ -60,7 +60,7 @@ export const IframeCanvasOld = memo((
`, [styleText])

const engine = useDesignerEngine()
const { components } = useDesignComponents()
const { components } = useDesignComponentsParams()
const themeMode = useThemeMode()

// useEffect(() => {
Expand Down
4 changes: 2 additions & 2 deletions src/core-react/canvas/ShadowDomCanvas/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useDesignerEngine } from "core-react/hooks";
import { useDesignComponents } from "core-react/hooks/useDesignComponents";
import { useDesignComponentsParams } from "core-react/hooks/useDesignComponentsParams";
import { ShadowCanvasImpl } from "core/shell/ShadowCanvasImpl";
import { MouseOverOutDriver } from "core/shell/drivers/MouseOverOutDriver";
import { memo, useCallback, useRef } from "react"
Expand All @@ -24,7 +24,7 @@ export const ShadowDomCanvas = memo((
const rootRef = useRef<ReactDOM.Root>()
const [viewType] = useDocumentViewTypeState(doc?.id)
const engine = useDesignerEngine()
const { components } = useDesignComponents()
const { components } = useDesignComponentsParams()

const handleRefChange = useCallback((host: HTMLElement | null) => {
if (host && engine ) {
Expand Down
15 changes: 14 additions & 1 deletion src/core-react/contexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,28 @@ export interface IComponentsParams {
registerComponents: (...components: IComponents[]) => void
}

export interface IDesignerComponentsParams extends IComponentsParams {
tools: IComponents,
registerTools: (...components: IComponents[]) => void
}

export const initialParams: IComponentsParams = {
components: {},
registerComponents: function (...components: IComponents[]): void {
throw new Error("Function not implemented.");
}
}

export const initialDesignerParams: IDesignerComponentsParams = {
...initialParams,
tools: {},
registerTools: function (...components: IComponents[]): void {
throw new Error("Function not implemented.");
}
}

export const DesignerEngineContext = createContext<IDesignerEngine | undefined>(undefined)
export const DesignComponentsContext = createContext<IComponentsParams>(initialParams)
export const DesignComponentsContext = createContext<IDesignerComponentsParams>(initialDesignerParams)
export const PreviewComponentsContext = createContext<IComponentsParams>(initialParams)
export const DocumentContext = createContext<IDocument | undefined>(undefined)
export const NodeContext = createContext<ITreeNode | undefined>(undefined)
Expand Down
4 changes: 2 additions & 2 deletions src/core-react/hooks/useDesignComponent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useDesignComponents } from "./useDesignComponents";
import { useDesignComponentsParams } from "./useDesignComponentsParams";

export function useDesignComponent(name?: string) {
const {components} = useDesignComponents();
const {components} = useDesignComponentsParams();
return name ? (components[name] || name): null
}
8 changes: 0 additions & 8 deletions src/core-react/hooks/useDesignComponents.ts

This file was deleted.

8 changes: 8 additions & 0 deletions src/core-react/hooks/useDesignComponentsParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { DesignComponentsContext, IDesignerComponentsParams } from "core-react/contexts";
import { useContext } from "react";

export function useDesignComponentsParams() {
const params = useContext<IDesignerComponentsParams>(DesignComponentsContext)

return params
}
12 changes: 12 additions & 0 deletions src/core-react/hooks/useGetElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useCallback } from "react";
import { useDesignerEngine } from "./useDesignerEngine";

export function useGetElement(){

const engine = useDesignerEngine()
const getElement = useCallback((rxId?:string)=>{
return rxId && engine?.getShell()?.getElement(rxId)
}, [engine])

return getElement
}
14 changes: 10 additions & 4 deletions src/core-react/hooks/useRegisterComponentMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { IComponentMaterial } from "core-react/interfaces";
import { isStr } from "core/utils/types";
import { useCallback } from "react";
import { useComponentManager } from "./useComponentManager";
import { useDesignComponents } from "./useDesignComponents";
import { useDesignComponentsParams } from "./useDesignComponentsParams";
import { useLocalesManager } from "./useLocalesManager";
import { usePreviewComponents } from "./usePreviewComponents";
import { useResourceManager } from "./useResourceManager";
Expand All @@ -11,12 +11,13 @@ export function useRegisterComponentMaterial() {
const resourceManager = useResourceManager()
const componentManager = useComponentManager()
const localesManager = useLocalesManager()
const { registerComponents: registerDesignComponents } = useDesignComponents()
const { registerComponents: registerDesignComponents, registerTools } = useDesignComponentsParams()
const { registerComponents: registerPreviewComponents } = usePreviewComponents()

const register = useCallback((meterial: IComponentMaterial, isSlot?:boolean) => {
const register = useCallback((meterial: IComponentMaterial, isSlot?: boolean) => {
const designers = { [meterial.componentName]: meterial.designer }
const previews = { [meterial.componentName]: meterial.component }
const tools = meterial.tools
componentManager?.registerComponents(meterial)
if (meterial.designerLocales) {
localesManager?.registerComponentLocales(meterial.componentName, meterial.designerLocales)
Expand All @@ -25,6 +26,10 @@ export function useRegisterComponentMaterial() {
localesManager?.registerResourceLocales(meterial.resource.resourceLocales)
}

if (meterial.toolsLocales) {
localesManager?.registerToolsLocales(meterial.toolsLocales)
}

for (const key of Object.keys(meterial.slots || {})) {
const slotMaterial = meterial.slots?.[key]
if (slotMaterial === true || slotMaterial === undefined || isStr(slotMaterial)) {
Expand All @@ -35,12 +40,13 @@ export function useRegisterComponentMaterial() {

registerDesignComponents(designers)
registerPreviewComponents(previews)
tools && registerTools(tools)

if (meterial.resource && !resourceManager?.getResourceByName(meterial.resource.name) && !isSlot) {
const resources = resourceManager?.registerResources(meterial.resource)
return (resources?.[0])
}
}, [componentManager, localesManager, registerDesignComponents, registerPreviewComponents, resourceManager])
}, [componentManager, localesManager, registerDesignComponents, registerPreviewComponents, registerTools, resourceManager])

return register
}
4 changes: 2 additions & 2 deletions src/core-react/hooks/useRegisterResource.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IMaterialResource } from "core-react/interfaces";
import { IResource } from "core/interfaces";
import { useCallback } from "react";
import { useLocalesManager } from "./useLocalesManager";
import { useResourceManager } from "./useResourceManager";
Expand All @@ -7,7 +7,7 @@ export function useRegisterResource() {
const resourceManager = useResourceManager()
const localesManager = useLocalesManager()

const register = useCallback((resource: IMaterialResource) => {
const register = useCallback((resource: IResource) => {

if (resource.resourceLocales) {
localesManager?.registerResourceLocales(resource.resourceLocales)
Expand Down
38 changes: 38 additions & 0 deletions src/core-react/hooks/useTreeNodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { ITreeNode, ID } from "core";
import { useCallback, useEffect, useState } from "react";
import { UnListener } from "runner/reaction";
import { useDesignerEngine } from "./useDesignerEngine";

export function useTreeNodes(ids: ID[]) {
const [nodes, setNodes] = useState<(ITreeNode | null)[] | null>()
const monitor = useDesignerEngine()?.getMonitor()
const handleNodeChange = useCallback((nd: ITreeNode) => {
setNodes(nodes => {
if (nodes?.find(node => node?.id === nd.id)) {
return nodes?.map(node => node?.id === nd.id ? nd : node)
}
return nodes;
})
}, [])

useEffect(() => {
if (monitor) {
const nds: (ITreeNode | null)[] = []
const offs: UnListener[] = []
for (const id of ids) {
nds.push(monitor.getNode(id))
offs.push(monitor?.subscribeToNodeChanged(id, handleNodeChange))
}
setNodes(nds)

return () => {
for (const off of offs) {
off?.()
}
}
}

}, [handleNodeChange, ids, monitor])

return nodes
}
34 changes: 11 additions & 23 deletions src/core-react/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,19 @@
import { IComponentConfig, IResource } from "core/interfaces";
import { ILocales } from "core/interfaces/loacales";
import React from "react";
import { IComponentConfig } from "core/interfaces";
import { ReactComponent } from "runner/ComponentRender/types";

//export type ReactComponent = React.FC<any> | React.ComponentClass<any>

export interface IComponents {
[key: string]: React.FC<any> | React.ComponentClass<any>
[key: string]: ReactComponent | undefined
}

export interface IMaterialResource extends IResource {
icon?: React.ReactElement,
color?: string,
resourceLocales?: ILocales,
imageUrl?: string,
}

export interface IComponentMaterial extends IComponentConfig {
packageName?: string //npm包名 生成代码用
component: React.FC<any> | React.ComponentClass<any>,
designer: React.FC<any> | React.ComponentClass<any>,
resource?: IMaterialResource,
export interface IComponentMaterial extends IComponentConfig<ReactComponent> {
//packageName?: string //npm包名 生成代码用
//resource?: IMaterialResource,
//slots用到的组件,值为true时,用缺省组件DefaultSlot, string时,存的是已经注册过的component resource名字
slots?: {
[name: string]: IComponentMaterial | true | string | undefined
},

//控制器
controller?: {

}
// slots?: {
// [name: string]: IComponentMaterial | true | string | undefined
// },
}

19 changes: 19 additions & 0 deletions src/core-react/switchRef.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { forwardRef, memo, useCallback } from "react"
import { ReactComponent } from "runner/ComponentRender/types"
import { isFunction } from "lodash"

type Callback = (element?: HTMLElement | null) => HTMLElement | undefined | null
const defaultCallback = (element?: HTMLElement | null) => element

export function switchRef(WrappedComponent: ReactComponent, callback: Callback = defaultCallback): ReactComponent {

return memo(forwardRef<HTMLInputElement>((props: any, ref) => {
const handleRefChange = useCallback((element: HTMLElement | null) => {
if (isFunction(ref)) {
ref(callback(element))
}
}, [ref])

return <WrappedComponent ref={handleRefChange} {...props} />
}))
}
23 changes: 23 additions & 0 deletions src/core-react/switchRefById.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { forwardRef, memo, useLayoutEffect } from "react"
import { ReactComponent } from "runner/ComponentRender/types"
import { useNode } from "./hooks/useNode"
import { isFunction } from "lodash"

type Callback = (element?: HTMLElement | null) => HTMLElement | undefined | null
const defaultCallback = (element?: HTMLElement | null) => element

export function switchRefById(WrappedComponent: ReactComponent, callback: Callback = defaultCallback): ReactComponent {

return memo(forwardRef<HTMLInputElement>((props: any, ref) => {
const node = useNode()
useLayoutEffect(() => {
const element = node?.id ? document.getElementById(node?.id) : null
if (isFunction(ref)) {
ref(callback(element))
}

}, [node?.id, ref])

return <WrappedComponent id={node?.id} {...props} />
}))
}
12 changes: 10 additions & 2 deletions src/core/interfaces/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ export interface IDesignerParams {
[key: string]: any
}

export interface IComponentConfig {
export interface IComponentConfig<ComponentType = any> {
packageName?: string //npm包名 生成代码用
componentName: string
component: ComponentType,
designer: ComponentType,
behaviorRule?: IBehaviorRule
designerSchema?: INodeSchema
designerLocales?: ILocales
Expand All @@ -51,7 +54,12 @@ export interface IComponentConfig {
//slots用到的组件,值为true时,用缺省组件DefaultSlot, string时,存的是已经注册过的component resource名字
slots?: {
[name: string]: IComponentConfig | true | string | undefined
}
},
//自定义属性面板用的多语言资源
toolsLocales?: ILocales
tools?: {
[name: string]: ComponentType | undefined
},
}

//可独立注册的行为规则
Expand Down
Loading

0 comments on commit b2fe944

Please sign in to comment.