Skip to content

Commit

Permalink
refactor: rewrite renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
Muluk-m committed Sep 19, 2022
1 parent d33d581 commit 5799f91
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 75 deletions.
99 changes: 99 additions & 0 deletions packages/vue3-schema-form/src/core/createCore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { Schema, SchemaFormProps } from '../types';
import { resolveSchemaWithSegments } from '../utils/resolver';
import { pick, isJsonSchema } from '../utils';

interface GlobalState {
disabled: boolean;
readonly: boolean;
border: boolean;
displayType: Schema['disabled'];
}

export type AddonMethods = Record<string, (...params: any[]) => any>;

type FieldScoped = {
name: string;
schema: Schema;
rootSchema: Schema;
props: Record<string, any>;
};

const calcFieldState = (schema: Schema, globalState: GlobalState) => {
return {
border: schema.border ?? globalState.border,
disabled: schema.disabled ?? globalState.disabled,
readonly: schema.readonly ?? globalState.readonly,
displayType: schema.displayType ?? globalState.displayType,
placeholder: schema.placeholder,
class: schema.className,
required: schema.required,
};
};

const generateSingleSchema = <M extends AddonMethods>(
schema: Schema,
globalState,
rootSchema: Schema,
methods: M
) => {
const fieldScoped: (FieldScoped & M & ReturnType<typeof calcFieldState>)[] = [];

for (const [field, property] of Object.entries(rootSchema.properties ?? {})) {
if (!property?.hidden) {
const fieldState = calcFieldState(property, globalState);
const fieldProps = pick(fieldState, ['readonly', 'disabled', 'class', 'placeholder']);

const singleField = {
name: field,
schema: property,
rootSchema,
...fieldState,
props: {
...fieldProps,
...(schema.props ?? {}),
},
...methods,
};

fieldScoped.push(singleField);
}
}

return fieldScoped;
};

export const createSchemaCore = ({
schema,
modelValue: formData,
disabled,
border,
readonly,
displayType,
deps,
}: SchemaFormProps) => {
if (!isJsonSchema(schema)) {
console.error('schema irregularities');
return null;
}

const rootSchema = resolveSchemaWithSegments(schema, formData, deps);

const globalState = {
border,
disabled,
readonly,
displayType,
};

const renderer = <M extends AddonMethods>(methods: M) =>
generateSingleSchema<M>(schema, globalState, rootSchema, methods);

return {
// TODO
errors: [],
formData,
schema: rootSchema,
globalState,
renderer,
};
};
86 changes: 11 additions & 75 deletions packages/vue3-schema-form/src/core/handleField.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,18 @@
import { inject } from 'vue';
import { SFPropsKey } from '../constants';
import { Schema, FormData, PayloadBoolean, SchemaFormProps, Widgets } from '../types';
import { isFunction, isObject } from '../utils';

export const getPayloadBoolean = (
payload: PayloadBoolean | undefined,
data: FormData,
globalState?: boolean
) => {
if (payload) {
return isFunction(payload) ? payload(data) : payload;
}

return globalState ?? false;
};

export const getFieldConfigs = ({
schema: rootSchema,
modelValue: formData,
disabled,
readonly,
}: SchemaFormProps) => {
const { properties, type } = rootSchema;

if (!properties || type !== 'object') {
console.error('schema irregularities');
return [];
}

const changeValueByName = (name: string, value: unknown) => {
if (formData) {
formData[name] = value;
}
};

const setFormData = (values: FormData) => {
for (const [key, value] of Object.entries(values)) {
changeValueByName(key, value);
}
};

const getFieldProps = (schema: Schema) => {
const addonConfigs = {
disabled: getPayloadBoolean(schema.disabled, formData, disabled),
readonly: getPayloadBoolean(schema.readonly, formData, readonly),
required: getPayloadBoolean(schema.required, formData),
placeholder: schema.placeholder,
class: schema.className,
};

return {
...addonConfigs,
rootSchema,
props: isObject(schema.props) ? { ...schema.props, ...addonConfigs } : addonConfigs,
changeValueByName,
setFormData,
};
};

const hideItems = (properties: Schema['properties']) =>
Object.fromEntries(
Object.entries(properties!).filter(([, { hidden }]) => !getPayloadBoolean(hidden, formData))
);

return Object.entries(hideItems(properties)).map(([name, schema]) => ({
name,
schema,
...getFieldProps(schema),
}));
};
import { SFRelationKey } from '../constants';
import { Schema, FormData, Widgets } from '../types';
import { useParent } from '../hooks/useRelation';

/**
* 获取字段的渲染控件
*/
export const getWidget = (itemSchema: Schema, defaultWidgets: Widgets) => {
const { type, widget } = itemSchema;
const rootProps = inject(SFPropsKey)!.value;
const { parent } = useParent(SFRelationKey);

const { props: rootProps } = parent!;
const widgetMap = {
...defaultWidgets,
...rootProps.widgets,
...rootProps.value.widgets,
};

let widgetName = 'default';
Expand All @@ -92,7 +26,9 @@ export const getWidget = (itemSchema: Schema, defaultWidgets: Widgets) => {
return widgetMap[widgetName];
};

export const handleRemoveHiddenData = (data: FormData, fieldsConfig: any) => {
const fieldNames = fieldsConfig.map(({ name }: any) => name);
/**
* TODO refactor
*/
export const handleRemoveHiddenData = (data: FormData, fieldNames: string[]) => {
return Object.fromEntries(Object.entries(data).filter(([key]) => fieldNames.includes(key)));
};

0 comments on commit 5799f91

Please sign in to comment.