-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
rdmclin2
committed
Jul 31, 2023
1 parent
9239fa7
commit 15acf3d
Showing
5 changed files
with
200 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
export interface BoundBox { | ||
width: number; | ||
height: number; | ||
} | ||
|
||
export type SizeFollow = 'sketch' | 'self'; | ||
|
||
/** | ||
* 组件尺寸控制 | ||
*/ | ||
export interface ComponentSize extends Partial<BoundBox> { | ||
widthFollow?: SizeFollow; | ||
heightFollow?: SizeFollow; | ||
} | ||
|
||
export type VerticalType = 'top' | 'center' | 'bottom'; | ||
export type HorizontalType = 'left' | 'center' | 'right'; | ||
|
||
export interface Alignment { | ||
/** | ||
* 横向位置 | ||
*/ | ||
vertical: VerticalType; | ||
/** | ||
* 纵向位置 | ||
*/ | ||
horizontal: HorizontalType; | ||
/** | ||
* 是否翻转相应的坐标系 | ||
*/ | ||
verticalFlipped?: boolean; | ||
} | ||
|
||
/** | ||
* C2D 组件预设值 | ||
*/ | ||
export interface C2DPresetValue { | ||
/** | ||
* 组件名 componentName | ||
*/ | ||
componentName: string; | ||
/** | ||
* 组件属性 | ||
*/ | ||
props: any; | ||
/** | ||
* 对齐方式 | ||
*/ | ||
alignment?: Alignment; | ||
/** | ||
* 组件大小 | ||
*/ | ||
size?: ComponentSize; | ||
/** | ||
* 如果存在配置属性,那么存在这里持久化保存 | ||
*/ | ||
config?: any; | ||
} | ||
|
||
export interface ReactNodeElement { | ||
$$__type: 'element'; | ||
$$__body: C2DPresetValue; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './c2d2c'; | ||
export * from './catogory'; | ||
export * from './field'; | ||
export * from './schema'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import { JSONSchema } from '@/types/schema'; | ||
import { isEmpty, isNil, omitBy, uniq } from 'lodash'; | ||
Check failure on line 2 in src/utils/c2d2c.tsx GitHub Actions / test
|
||
import { ReactNodeElement } from '../types'; | ||
|
||
/** | ||
* 从schema 获取预设值 | ||
* @param schema | ||
*/ | ||
export const getDefaultValueFromSchema = (schema: JSONSchema) => { | ||
if (schema.type === 'object') { | ||
if (!schema.properties) return; | ||
return Object.fromEntries( | ||
Object.entries(schema.properties).map(([key, value]) => [key, value.default]), | ||
); | ||
} | ||
if (schema.type === 'null') return null; | ||
return schema.default; | ||
}; | ||
|
||
/** | ||
* 获取组件库导入代码 | ||
*/ | ||
export const generateImportCode = (pkg: string, components: string[]) => { | ||
return `import { ${uniq(components).join(', ')} } from '${pkg}';`; | ||
}; | ||
|
||
/** | ||
* 将 prop 转换成字符串 | ||
*/ | ||
export const createPropString = ( | ||
key: string, | ||
// eslint-disable-next-line @typescript-eslint/ban-types | ||
value: string | number | boolean | symbol | object | undefined | Function | any[], | ||
) => { | ||
switch (typeof value) { | ||
case 'undefined': | ||
return ''; | ||
case 'object': | ||
// 数组 | ||
if (value instanceof Array) { | ||
return `${key}={${JSON.stringify(value)}}`; | ||
} | ||
|
||
// eslint-disable-next-line no-case-declarations | ||
const clearValue = omitBy(value, isNil); | ||
// 如果 object 里不存在任何值,返回空 | ||
if (Object.values(clearValue).length === 0) return ''; | ||
|
||
// eslint-disable-next-line no-case-declarations | ||
const genObjStr = () => { | ||
// 如果包含 $$__type 属性,说明是 ReactNode 或 icon | ||
if ((value as ReactNodeElement).$$__type) { | ||
// eslint-disable-next-line @typescript-eslint/no-use-before-define | ||
return genChildrenJSXCode(value as ReactNodeElement); | ||
} | ||
|
||
return JSON.stringify(clearValue, null); | ||
}; | ||
|
||
return `${key}={${genObjStr()}}`; | ||
case 'boolean': | ||
if (value) return `${key}`; | ||
|
||
return `${key}={${value}}`; | ||
case 'number': | ||
return `${key}={${value}}`; | ||
case 'string': | ||
if (isEmpty(value)) return ''; | ||
|
||
return `${key}="${value}"`; | ||
case 'function': | ||
return `${key}={${value.toString()}}`; | ||
case 'symbol': | ||
return `${key}={Symbol.for('${value.description}')}`; | ||
} | ||
}; | ||
|
||
/** | ||
* 生成 React JSX 代码 | ||
* @param component | ||
* @param props | ||
* @param PropStringFn | ||
*/ | ||
export const generateJSXCode = ( | ||
component: string, | ||
props: Record<string, any>, | ||
PropStringFn = createPropString, | ||
) => { | ||
if (!props) { | ||
return `<${component} />`; | ||
} | ||
|
||
const inline = !props.children; | ||
|
||
const propsStr = Object.entries(props) | ||
// 针对 children 有值的情况下,在 props 上过滤掉 children | ||
.filter((v) => (inline ? v : v[0] !== 'children')) | ||
.map((entry) => PropStringFn(entry[0], entry[1])) | ||
// 过滤空的对象 | ||
.filter((v) => v) | ||
.join(' '); | ||
|
||
if (inline) return `<${component} ${propsStr}/>`; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-use-before-define | ||
return `<${component} ${propsStr}>${genChildrenJSXCode(props.children)}</${component}>`; | ||
}; | ||
|
||
/** | ||
* 生成子 JSX 代码 | ||
* @param children | ||
*/ | ||
const genChildrenJSXCode = (children: string | ReactNodeElement | ReactNodeElement[]): string => { | ||
// children 为字符串的场景 | ||
if (typeof children === 'string') { | ||
return children; | ||
} | ||
|
||
const renderChildNode = (child: ReactNodeElement) => { | ||
const { $$__type, $$__body } = child; | ||
|
||
switch ($$__type) { | ||
// children 为子组件的场景 | ||
case 'element': | ||
return generateJSXCode($$__body.componentName, $$__body.props); | ||
// TODO: children 为 Icon 的场景 | ||
} | ||
}; | ||
|
||
if (children instanceof Array) { | ||
return children.map(renderChildNode).join('\n'); | ||
} | ||
|
||
return renderChildNode(children); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
export * from './autoId'; | ||
export * from './schema'; | ||
export * from './c2d2c'; |
This file was deleted.
Oops, something went wrong.