import { FC, ReactNode } from '../../node_modules/react'; import { ColorType, Component, RuntimeScene, VirtualChildComponent } from '@easytwin/runtime'; import { ButtonProps } from '@easyv/react-components'; import { RadioGroupProps } from '@easyv/react-components/dist/Radio'; import { FilterFunction } from '../UIGenerator'; export type InputNumberProps = { /** 输入0-100 输出给引擎0-1 */ percent?: boolean; /** type: number */ fieldName: FieldName; min?: number; max?: number; prefix?: string; suffix?: string; precisionOnShow?: number; precisionOnSave?: number; }; export type InputSliderProps = { className?: string; /** type: number */ fieldName: FieldName; step?: number; min?: number; max?: number; prefix?: string; suffix?: string; /** 只限制滑动条的输入范围,默认为true */ limitSliderOnly?: boolean; /** 显示数字输入框,默认为true */ showInput?: boolean; precisionOnShow?: number; precisionOnSave?: number; }; export type UISchemaFunc = (comp: C, json: S) => UISchema; type FieldName = string; type BaseUIProps = { tooltip?: ReactNode; label: string; text?: ReactNode; hidden?: boolean; disabled?: boolean; }; type UIType2Props = { Select: { /** type: string | number union */ fieldName: FieldName; options: { key: string | number; label: string; img?: string; }[]; allowClear?: boolean; } & BaseUIProps; /** type: number */ InputNumber: InputNumberProps & BaseUIProps; /** type: number */ InputEulerNumber: Omit & BaseUIProps; /** 数据结构上独立,ui上在一行 (type: number) * N */ InputNumberGroup: { inputNumbers: InputNumberProps[]; } & BaseUIProps; InputVector2: { /** type: vector2 */ fieldName: FieldName; min?: number; max?: number; prefix?: [string, string]; suffix?: [string, string]; constrainable?: boolean; precisionOnShow?: number; precisionOnSave?: number; } & BaseUIProps; InputVector3: { /** type: vector3 */ fieldName: FieldName; useEuler?: boolean; prefix?: [string, string, string]; min?: number; max?: number; suffix?: string; constrainable?: boolean; hideY?: boolean; hideZ?: boolean; hideX?: boolean; precisionOnShow?: number; precisionOnSave?: number; } & BaseUIProps; InputSlider: InputSliderProps & BaseUIProps; InputEulerSlider: InputSliderProps & BaseUIProps; InputSliderForTime: InputSliderProps & BaseUIProps; InputText: { /** type: string */ fieldName: FieldName; prefix?: string; suffix?: string; maxLength?: number; } & BaseUIProps; ColorPicker: { /** type为ColorType[]时是 MultiTypeColor,为ColorType时是 MultiColorValueMap[type] */ fieldName: FieldName; type: ColorType[] | ColorType; disableAlpha?: boolean; disableOutputAlpha?: boolean; } & BaseUIProps; CheckBox: { /** type: boolean | any */ fieldName: FieldName; /** 设置checked为true和false时的值 */ overrideValue?: [trueValue: any, falseValue: any]; } & BaseUIProps; /** type: boolean[], 每个checkbox绑定的属性可以是独立的,只是显示在一行里 */ CheckBoxGroup: { checkboxes: { /** type: boolean */ fieldName: FieldName; label?: ReactNode; disabled?: boolean; }[]; } & BaseUIProps; /** type: string, 同时只允许一个Icon高亮,每个Icon有自己的string值 */ ToggleStringIconGroup: { /** type: string union */ fieldName: FieldName; icons: { key: string; tooltip?: ReactNode; icon: React.ReactNode; disabled?: boolean; }[]; } & BaseUIProps; FileUpload: { /** type: string */ fieldName: FieldName; /** @example ['jpg','png'] */ accept: string[]; /** 单位: B */ maxFileSize?: number; /** 单位: B */ maxImageSize?: number; /** 单位: B */ maxModelSize?: number; } & BaseUIProps; Button: { text: string; style?: ButtonProps['style']; type?: ButtonProps['type']; size?: ButtonProps['size']; disableTab?: boolean; onClick: (e: Event) => void; } & BaseUIProps; ButtonGroup: { buttons: { text: string; disabled?: boolean; style?: ButtonProps['style']; type?: ButtonProps['type']; size?: ButtonProps['size']; onClick: () => void; }[]; } & BaseUIProps; Group: { /** 'default' 只设置label文字颜色; 'area' 用于自定义组件的一块渲染区域(hover会改变背景色) */ type?: 'area' | 'default'; /** 显示连接线 */ showConnectionLine?: boolean; /** 隐藏折叠Icon */ disableFold?: boolean; /** 显示分割线 */ showDivider?: boolean; children: UIPrimitive[]; titleExtra?: React.ReactNode; /** 是否显示子组件 */ showChildren?: boolean; } & BaseUIProps; PureGroup: { children: UIPrimitive[]; hidden?: boolean; disabled?: boolean; }; Tabs: { hidden?: boolean; /** type: { id: string , name?: string }[] */ fieldName: FieldName; title: string; showConnectionLine?: boolean; /** 显示折叠Icon */ disableFold?: boolean; childSchema: UISchema | UISchemaFunc; /** 如果为空则使用fieldName中的name,否则 */ useValueName?: boolean; /** 默认不选中第一个状态 */ allowEmpty?: boolean; /** 用于新增数组项时获取数据 */ onAddItem: () => any; onTabChange?: (index: number | undefined, id: string | undefined) => void; /** 覆写内部的添加逻辑(需要自行处理数据的保存和同步, item为onAddItem的返回值 */ onItemAdd?: (item: any) => void; /** 覆写内部的添加逻辑(需要自行处理数据的保存和同步)*/ onItemRemove?: (item: any) => void; selectKey?: string; setSelectKey?: (key: string | undefined) => void; }; Custom: { ui: FC; disabled?: boolean; hidden?: boolean; }; TextureSelect: { /** type: string */ fieldName: FieldName; } & BaseUIProps; Radio: { /** type: boolean */ fieldName: FieldName; className?: string; } & BaseUIProps; RadioGroup: { /** type: any[] */ fieldName: FieldName; values: { label: string; value: any; children?: ReactNode | ((value: { checked: boolean; }) => ReactNode); }[]; buttonStyle?: RadioGroupProps['buttonStyle']; type?: RadioGroupProps['type']; size?: RadioGroupProps['size']; } & BaseUIProps; TextStyle: { /** type: TextStyle */ fieldName: FieldName; } & BaseUIProps; GridMatrix: { /** type: IVector2 */ fieldName: FieldName; } & BaseUIProps; ParticleSystemBaseInput: { /** type: ParticleSystemBaseInputType */ fieldName: FieldName; suffix?: ReactNode; /** if true, will show in euler but save in radian */ useEuler?: boolean; } & BaseUIProps; EntitySelect: { /** type: EntitySelectType */ fieldName: FieldName; scene: RuntimeScene; showSearch?: boolean; placeHolder?: string; filter?: string[] | FilterFunction; } & BaseUIProps; }; export interface CustomUIProps { comp: COMP; /** 来自UIGenerator的json */ json: JSON; disabled: boolean; onChange: (name: string, value: unknown) => void; onConfirm: (name: string, value: unknown) => void; } type UIType = keyof UIType2Props; type UIConfig = { [UI in UIType]: { uiType: UI; } & UIType2Props[UI]; }; export type UIPrimitive = UIConfig[UIType] | undefined; export type UISchema = UIPrimitive[]; export {};