import { ReactElement, CSSProperties, ReactNode, JSX } from 'react'; type ItemSelector = { index: number; zone?: string; }; type FieldOption = { label: string; value: string | number | boolean | undefined | null | object; }; type FieldOptions = Array | ReadonlyArray; type BaseField = { label?: string; labelIcon?: ReactElement; metadata?: Metadata; visible?: boolean; }; type TextField = BaseField & { type: "text"; placeholder?: string; contentEditable?: boolean; }; type NumberField = BaseField & { type: "number"; placeholder?: string; min?: number; max?: number; step?: number; }; type TextareaField = BaseField & { type: "textarea"; placeholder?: string; contentEditable?: boolean; }; type SelectField = BaseField & { type: "select"; options: FieldOptions; }; type RadioField = BaseField & { type: "radio"; options: FieldOptions; }; type ArrayField = BaseField & { type: "array"; arrayFields: { [SubPropName in keyof Props[0]]: UserField extends { type: PropertyKey; } ? Field | UserField : Field; }; defaultItemProps?: Props[0]; getItemSummary?: (item: Props[0], index?: number) => string; max?: number; min?: number; }; type ObjectField = BaseField & { type: "object"; objectFields: { [SubPropName in keyof Props]: UserField extends { type: PropertyKey; } ? Field | UserField : Field; }; }; type Adaptor = {}, PropShape = TableShape> = { name: string; fetchList: (adaptorParams?: AdaptorParams) => Promise; mapProp?: (value: TableShape) => PropShape; }; type NotUndefined = T extends undefined ? never : T; type ExternalFieldWithAdaptor = BaseField & { type: "external"; placeholder?: string; adaptor: Adaptor; adaptorParams?: object; getItemSummary: (item: NotUndefined, index?: number) => string; }; type ExternalField = BaseField & { type: "external"; placeholder?: string; fetchList: (params: { query: string; filters: Record; }) => Promise; mapProp?: (value: any) => Props; mapRow?: (value: any) => Record; getItemSummary?: (item: NotUndefined, index?: number) => string; showSearch?: boolean; renderFooter?: (props: { items: any[]; }) => ReactElement; initialQuery?: string; filterFields?: Record; initialFilters?: Record; }; type CustomFieldRender = (props: { field: CustomField; name: string; id: string; value: Value; onChange: (value: Value) => void; readOnly?: boolean; }) => ReactElement; type CustomField = BaseField & { type: "custom"; render: CustomFieldRender; contentEditable?: boolean; }; type SlotField = BaseField & { type: "slot"; allow?: string[]; disallow?: string[]; }; type Field = TextField | NumberField | TextareaField | SelectField | RadioField | ArrayField | ObjectField | ExternalField | ExternalFieldWithAdaptor | CustomField | SlotField; type Fields = { [PropName in keyof Omit]: UserField extends { type: PropertyKey; } ? Field | UserField : Field; }; type FieldProps, ValueType = any> = { field: F; value: ValueType; id?: string; onChange: (value: ValueType, uiState?: Partial) => void; readOnly?: boolean; }; type DropZoneProps = { zone: string; allow?: string[]; disallow?: string[]; style?: CSSProperties; minEmptyHeight?: number; className?: string; collisionAxis?: DragAxis; }; type PuckContext = { renderDropZone: React.FC; metadata: Metadata; isEditing: boolean; dragRef: ((element: Element | null) => void) | null; }; type DefaultRootFieldProps = { title?: string; }; type DefaultComponentProps = { [key: string]: any; }; type WithId = Props & { id: string; }; type WithPuckProps = Props & { puck: PuckContext; editMode?: boolean; }; type AsFieldProps = Omit; type WithChildren = Props & { children: ReactNode; }; type UserGenerics = ExtractConfigParams, UserData extends Data | Data = Data, UserAppState extends PrivateAppState = PrivateAppState, UserPublicAppState extends AppState = AppState, UserComponentData extends ComponentData = UserData["content"][0]> = { UserConfig: UserConfig; UserParams: UserParams; UserProps: UserParams["props"]; UserRootProps: UserParams["rootProps"] & DefaultRootFieldProps; UserData: UserData; UserAppState: UserAppState; UserPublicAppState: UserPublicAppState; UserComponentData: UserComponentData; UserField: UserParams["field"]; }; type ExtractField = Extract; type SlotComponent = (props?: Omit) => ReactNode; type PuckComponent = (props: WithId; }>>) => JSX.Element; type ResolveDataTrigger = "insert" | "replace" | "load" | "force"; type WithPartialProps = Omit & { props?: Partial; }; type ComponentConfigInternal, "type">, // NB this doesn't include AllProps, so types will not contain deep slot types. To fix, we require a breaking change. UserField extends BaseField = {}> = { render: PuckComponent; label?: string; defaultProps?: FieldProps; fields?: Fields; permissions?: Partial; inline?: boolean; resolveFields?: (data: DataShape, params: { changed: Partial & { id: string; }>; fields: Fields; lastFields: Fields; lastData: DataShape | null; appState: AppState; parent: ComponentData | null; }) => Promise> | Fields; resolveData?: (data: DataShape, params: { changed: Partial & { id: string; }>; lastData: DataShape | null; metadata: Metadata; trigger: ResolveDataTrigger; }) => Promise> | WithPartialProps; resolvePermissions?: (data: DataShape, params: { changed: Partial & { id: string; }>; lastPermissions: Partial; permissions: Partial; appState: AppState; lastData: DataShape | null; }) => Promise> | Partial; metadata?: Metadata; }; type RootConfigInternal = Partial, AsFieldProps, RootData>, UserField>>; type Category = { components?: ComponentName[]; title?: string; visible?: boolean; defaultExpanded?: boolean; }; type ConfigInternal = { categories?: Record> & { other?: Category; }; components: { [ComponentName in keyof Props]: Omit, "type">, UserField>, "type">; }; root?: RootConfigInternal; }; type DefaultComponents = Record; type Config = DefaultComponents | ConfigParams, RootProps extends DefaultComponentProps = any, CategoryName extends string = string> = PropsOrParams extends ConfigParams ? ConfigInternal : PropsOrParams extends ConfigParams ? ConfigInternal : PropsOrParams extends ConfigParams ? ConfigInternal : ConfigInternal; type ExtractConfigParams = UserConfig extends ConfigInternal ? { props: PropsOrParams; rootProps: RootProps & DefaultRootFieldProps; categoryNames: CategoryName; field: UserField extends { type: string; } ? UserField : Field; } : never; type BaseData = { readOnly?: Partial>; }; type RootDataWithProps = BaseData & { props: Props; }; type RootDataWithoutProps = Props; type RootData = Partial>> & Partial>; type ComponentData = Record> = { type: Name; props: WithDeepSlots, Content>; } & BaseData; type ComponentDataOptionalId = { type: Name; props: Props & { id?: string; }; } & BaseData; type ComponentDataMap = { [K in keyof Components]: ComponentData; }[keyof Components]; type Content = ComponentDataMap[]; type Data = { root: WithDeepSlots, Content>; content: Content; zones?: Record>; }; type Metadata = { [key: string]: any; }; type ItemWithId = { _arrayId: string; _originalIndex: number; }; type ArrayState = { items: ItemWithId[]; openId: string; }; type UiState = { leftSideBarVisible: boolean; rightSideBarVisible: boolean; leftSideBarWidth?: number | null; rightSideBarWidth?: number | null; itemSelector: ItemSelector | null; arrayState: Record; previewMode: "interactive" | "edit"; componentList: Record; isDragging: boolean; viewports: { current: { width: number; height: number | "auto"; }; controlsVisible: boolean; options: Viewport[]; }; field: { focus?: string | null; }; }; type AppState = { data: UserData; ui: UiState; }; type ZoneType = "root" | "dropzone" | "slot"; type PuckNodeData = { data: ComponentData; flatData: ComponentData; parentId: string | null; zone: string; path: string[]; }; type PuckZoneData = { contentIds: string[]; type: ZoneType; }; type NodeIndex = Record; type ZoneIndex = Record; type PrivateAppState = AppState & { indexes: { nodes: NodeIndex; zones: ZoneIndex; }; }; type BuiltinTypes = Date | RegExp | Error | Function | symbol | null | undefined; /** * Recursively walk T and replace Slots with SlotComponents */ type WithDeepSlots = T extends Slot ? SlotType : T extends (infer U)[] ? Array> : T extends (infer U)[] ? WithDeepSlots[] : T extends BuiltinTypes ? T : T extends object ? { [K in keyof T]: WithDeepSlots; } : T; type ConfigParams = { components?: Components; root?: RootProps; categories?: CategoryNames; fields?: AssertHasValue; }; type FieldsExtension = { [Type in string]: { type: Type; }; }; type Exact = Record, never>; type LeftOrExactRight = (Left & Union extends Right ? Exact : Left) | (Right & Exact); type AssertHasValue = [keyof T] extends [ never ] ? False : True; type MapFnParams = { value: any; parentId: string; propName: string; field: ThisField; propPath: string; }; type FieldTransformFnParams = Omit, "parentId"> & { isReadOnly: boolean; componentId: string; }; type FieldTransformFn = (params: FieldTransformFnParams) => any; type FieldTransforms, // Setting fields: {} helps TS choose default field types G extends UserGenerics = UserGenerics, UserField extends { type: string; } = Field | G["UserField"]> = Partial<{ [Type in UserField["type"]]: FieldTransformFn>; }>; type RenderFunc = (props: Props) => ReactElement; declare const overrideKeys: readonly ["header", "headerActions", "fields", "fieldLabel", "drawer", "drawerItem", "componentOverlay", "outline", "puck", "preview"]; type OverrideKey = (typeof overrideKeys)[number]; type OverridesGeneric = Shape; type Overrides = OverridesGeneric<{ fieldTypes: Partial>; header: RenderFunc<{ actions: ReactNode; children: ReactNode; }>; actionBar: RenderFunc<{ label?: string; children: ReactNode; parentAction: ReactNode; }>; headerActions: RenderFunc<{ children: ReactNode; }>; preview: RenderFunc; fields: RenderFunc<{ children: ReactNode; isLoading: boolean; itemSelector?: ItemSelector | null; }>; fieldLabel: RenderFunc<{ children?: ReactNode; icon?: ReactNode; label: string; el?: "label" | "div"; readOnly?: boolean; className?: string; }>; components: RenderFunc; componentItem: RenderFunc<{ children: ReactNode; name: string; }>; drawer: RenderFunc; drawerItem: RenderFunc<{ children: ReactNode; name: string; }>; iframe: RenderFunc<{ children: ReactNode; document?: Document; }>; outline: RenderFunc; componentOverlay: RenderFunc<{ children: ReactNode; hover: boolean; isSelected: boolean; componentId: string; componentType: string; }>; puck: RenderFunc; }>; type FieldRenderFunctions = UserGenerics, UserField extends { type: string; } = Field | G["UserField"]> = Omit<{ [Type in UserField["type"]]: React.FunctionComponent, any> & { children: ReactNode; name: string; }>; }, "custom">; type DragAxis = "dynamic" | "y" | "x"; type iconTypes = "Smartphone" | "Monitor" | "Tablet"; type Viewport = { width: number; height?: number | "auto"; label?: string; icon?: iconTypes | ReactNode; }; type Permissions = { drag: boolean; duplicate: boolean; delete: boolean; edit: boolean; insert: boolean; } & Record; type Plugin = { overrides?: Partial>; fieldTransforms?: FieldTransforms; }; type Slot = { [K in keyof Props]: ComponentDataOptionalId; }[keyof Props][]; declare const headingAnalyzer: Plugin; export { headingAnalyzer as default };