/** @packageDocumentation
 * @module Content
 */
import { Id64String } from "@itwin/core-bentley";
import { ClassInfo, CompressedClassInfoJSON, RelationshipPath, RelationshipPathJSON, StrippedRelationshipPath } from "../EC.js";
import { RelationshipMeaning } from "../rules/content/modifiers/RelatedPropertiesSpecification.js";
import { CategoryDescription } from "./Category.js";
import { EditorDescription } from "./Editor.js";
import { Property, PropertyJSON } from "./Property.js";
import { RendererDescription } from "./Renderer.js";
import { TypeDescription } from "./TypeDescription.js";
/**
 * Data structure for a [[Field]] serialized to JSON.
 * @public
 */
export interface BaseFieldJSON {
    category: string;
    name: string;
    label: string;
    type: TypeDescription;
    isReadonly: boolean;
    priority: number;
    renderer?: RendererDescription;
    editor?: EditorDescription;
    extendedData?: {
        [key: string]: unknown;
    };
}
/**
 * Data structure for a [[PropertiesField]] serialized to JSON.
 * @public
 */
export interface PropertiesFieldJSON<TClassInfoJSON = ClassInfo> extends BaseFieldJSON {
    properties: PropertyJSON<TClassInfoJSON>[];
}
/**
 * Data structure for a [[ArrayPropertiesField]] serialized to JSON.
 * @public
 */
export interface ArrayPropertiesFieldJSON<TClassInfoJSON = ClassInfo> extends PropertiesFieldJSON<TClassInfoJSON> {
    itemsField: PropertiesFieldJSON<TClassInfoJSON>;
}
/**
 * Data structure for a [[StructPropertiesField]] serialized to JSON.
 * @public
 */
export interface StructPropertiesFieldJSON<TClassInfoJSON = ClassInfo> extends PropertiesFieldJSON<TClassInfoJSON> {
    memberFields: PropertiesFieldJSON<TClassInfoJSON>[];
}
/**
 * Data structure for a [[NestedContentField]] serialized to JSON.
 * @public
 */
export interface NestedContentFieldJSON<TClassInfoJSON = ClassInfo> extends BaseFieldJSON {
    contentClassInfo: TClassInfoJSON;
    pathToPrimaryClass: RelationshipPathJSON<TClassInfoJSON>;
    relationshipMeaning?: RelationshipMeaning;
    actualPrimaryClassIds?: Id64String[];
    autoExpand?: boolean;
    nestedFields: FieldJSON<TClassInfoJSON>[];
}
/**
 * JSON representation of a [[Field]]
 * @public
 */
export type FieldJSON<TClassInfoJSON = ClassInfo> = BaseFieldJSON | PropertiesFieldJSON<TClassInfoJSON> | ArrayPropertiesFieldJSON<TClassInfoJSON> | StructPropertiesFieldJSON<TClassInfoJSON> | NestedContentFieldJSON<TClassInfoJSON>;
/**
 * An interface of an object that can return content [[Field]] by its name. Implemented by some field types that
 * reference other fields: [[NestedContentField]], [[StructPropertiesField]], [[ArrayPropertiesField]].
 *
 * @public
 */
interface IFieldsSource {
    getFieldByName: (name: string) => Field | undefined;
}
/**
 * Props for creating [[Field]].
 * @public
 */
interface FieldProps {
    /** Category information */
    category: CategoryDescription;
    /** Unique name */
    name: string;
    /** Display label */
    label: string;
    /** Description of this field's values data type */
    type: TypeDescription;
    /** Are values in this field read-only */
    isReadonly: boolean;
    /** Priority of the field */
    priority: number;
    /** Property editor used to edit values of this field */
    editor?: EditorDescription;
    /** Property renderer used to render values of this field */
    renderer?: RendererDescription;
    /** Extended data associated with this field */
    extendedData?: {
        [key: string]: unknown;
    };
}
/**
 * Describes a single content field. A field is usually represented as a grid column
 * or a property pane row.
 *
 * @public
 */
export declare class Field implements FieldProps {
    /** Category information */
    category: CategoryDescription;
    /** Unique name */
    name: string;
    /** Display label */
    label: string;
    /** Description of this field's values data type */
    type: TypeDescription;
    /** Are values in this field read-only */
    isReadonly: boolean;
    /** Priority of the field. Higher priority fields should appear first in the UI */
    priority: number;
    /** Property renderer used to render values of this field */
    renderer?: RendererDescription;
    /** Property editor used to edit values of this field */
    editor?: EditorDescription;
    /** Extended data associated with this field */
    extendedData?: {
        [key: string]: unknown;
    };
    /** Parent field */
    private _parent?;
    /**
     * Creates an instance of [[Field]].
     * @param category Category information
     * @param name Unique name
     * @param label Display label
     * @param type Description of this field's values data type
     * @param isReadonly Are values in this field read-only
     * @param priority Priority of the field
     * @param editor Property editor used to edit values of this field
     * @param renderer Property renderer used to render values of this field
     * @param extendedData Extended data associated with this field
     * @deprecated in 5.0 - might be removed in next major version. Use an overload with `FieldProps` instead.
     */
    constructor(category: CategoryDescription, name: string, label: string, type: TypeDescription, isReadonly: boolean, priority: number, editor?: EditorDescription, renderer?: RendererDescription, extendedData?: {
        [key: string]: unknown;
    });
    /** Creates an instance of [[Field]]. */
    constructor(props: FieldProps);
    /**
     * Is this a [[PropertiesField]]
     */
    isPropertiesField(): this is PropertiesField;
    /**
     * Is this a [[NestedContentField]]
     */
    isNestedContentField(): this is NestedContentField;
    /**
     * Get parent
     */
    get parent(): NestedContentField | undefined;
    clone(): Field;
    /**
     * Serialize this object to JSON.
     * @deprecated in 5.0 - might be removed in next major version. Use [[toCompressedJSON]] instead.
     */
    toJSON(): FieldJSON;
    /** Serialize this object to compressed JSON */
    toCompressedJSON(_classesMap: {
        [id: string]: CompressedClassInfoJSON;
    }): FieldJSON<string>;
    /**
     * Deserialize [[Field]] from JSON.
     * @deprecated in 5.0 - might be removed in next major version. Use [[fromCompressedJSON]] instead.
     */
    static fromJSON(json: FieldJSON | undefined, categories: CategoryDescription[]): Field | undefined;
    /** Deserialize a [[Field]] from compressed JSON. */
    static fromCompressedJSON(json: FieldJSON<string> | undefined, classesMap: {
        [id: string]: CompressedClassInfoJSON;
    }, categories: CategoryDescription[]): Field | undefined;
    protected static getCategoryFromFieldJson(fieldJson: FieldJSON, categories: CategoryDescription[]): CategoryDescription;
    /** Resets field's parent. */
    resetParentship(): void;
    /** Sets provided [[NestedContentField]] as parent of this field. */
    rebuildParentship(parentField?: NestedContentField): void;
    /**
     * Get descriptor for this field.
     * @public
     */
    getFieldDescriptor(): FieldDescriptor;
    /**
     * Checks if this field matches given field descriptor
     * @see [[getFieldDescriptor]]
     */
    matchesDescriptor(descriptor: FieldDescriptor): boolean;
}
/**
 * Props for creating [[PropertiesField]].
 * @public
 */
interface PropertiesFieldProps extends FieldProps {
    /** A list of properties this field is created from */
    properties: Property[];
}
/**
 * Describes a content field that's based on one or more similar
 * EC properties.
 *
 * @public
 */
export declare class PropertiesField extends Field implements PropertiesFieldProps {
    #private;
    /** A list of properties this field is created from */
    properties: Property[];
    /**
     * Creates an instance of [[PropertiesField]].
     * @param category Category information
     * @param name Unique name
     * @param label Display label
     * @param type Description of this field's values data type
     * @param isReadonly Are values in this field read-only
     * @param priority Priority of the field
     * @param properties A list of properties this field is created from
     * @param editor Property editor used to edit values of this field
     * @param renderer Property renderer used to render values of this field
     * @deprecated in 5.0 - might be removed in next major version. Use an overload with `PropertiesFieldProps` instead.
     */
    constructor(category: CategoryDescription, name: string, label: string, type: TypeDescription, isReadonly: boolean, priority: number, properties: Property[], editor?: EditorDescription, renderer?: RendererDescription);
    /** Creates an instance of [[PropertiesField]]. */
    constructor(props: PropertiesFieldProps);
    /**
     * Sets provided [[NestedContentField]] as parent of this field.
     * @throws [[PresentationError]] if this field already has `parentArrayField` or `parentStructField`.
     */
    rebuildParentship(parentField?: NestedContentField): void;
    /**
     * Returns parent struct field that this field is part of, or sets the provided [[StructPropertiesField]]
     * as `parentStructField` of this field.
     *
     * @throws [[PresentationError]] if this field already has `parentArrayField` or `parent`.
     */
    get parentStructField(): StructPropertiesField | undefined;
    set parentStructField(field: StructPropertiesField | undefined);
    /** Returns parent array field that this field is part of, or sets the provided [[ArrayPropertiesField]]
     * as `parentArrayField` of this field.
     *
     * @throws [[PresentationError]] if this field already has `parentStructField` or `parent`.
     */
    get parentArrayField(): ArrayPropertiesField | undefined;
    set parentArrayField(field: ArrayPropertiesField | undefined);
    /** Is this a an array property field */
    isArrayPropertiesField(): this is ArrayPropertiesField;
    /** Is this a an struct property field */
    isStructPropertiesField(): this is StructPropertiesField;
    clone(): PropertiesField;
    /**
     * Serialize this object to JSON
     * @deprecated in 5.0 - might be removed in next major version. Use [[toCompressedJSON]] instead.
     */
    toJSON(): PropertiesFieldJSON;
    /** Serialize this object to compressed JSON */
    toCompressedJSON(classesMap: {
        [id: string]: CompressedClassInfoJSON;
    }): PropertiesFieldJSON<string>;
    /**
     * Deserialize [[PropertiesField]] from JSON.
     * @deprecated in 5.0 - might be removed in next major version. Use [[fromCompressedJSON]] instead.
     */
    static fromJSON(json: PropertiesFieldJSON | undefined, categories: CategoryDescription[]): PropertiesField | undefined;
    /**
     * Deserialize a [[PropertiesField]] from compressed JSON.
     * @public
     */
    static fromCompressedJSON(json: PropertiesFieldJSON<Id64String>, classesMap: {
        [id: string]: CompressedClassInfoJSON;
    }, categories: CategoryDescription[]): PropertiesField | undefined;
    /**
     * Get descriptor for this field.
     * @public
     */
    getFieldDescriptor(): FieldDescriptor;
    /**
     * Checks if this field matches given field descriptor
     * @see [[getFieldDescriptor]]
     */
    matchesDescriptor(descriptor: FieldDescriptor): boolean;
}
/**
 * Props for creating [[ArrayPropertiesField]].
 * @public
 */
interface ArrayPropertiesFieldProps extends PropertiesFieldProps {
    itemsField: PropertiesField;
}
/**
 * Describes a content field that's based on one or more similar EC array properties.
 * @public
 */
export declare class ArrayPropertiesField extends PropertiesField implements ArrayPropertiesFieldProps, IFieldsSource {
    #private;
    /**
     * Creates an instance of [[ArrayPropertiesField]].
     * @deprecated in 5.0 - might be removed in next major version. Use an overload with `ArrayPropertiesFieldProps` instead.
     */
    constructor(category: CategoryDescription, name: string, label: string, type: TypeDescription, itemsField: PropertiesField, isReadonly: boolean, priority: number, properties: Property[], editor?: EditorDescription, renderer?: RendererDescription);
    /** Creates an instance of [[ArrayPropertiesField]]. */
    constructor(props: ArrayPropertiesFieldProps);
    /** Returns or sets the array items field. When setting, updates `parentArrayField` of the items field to this field. */
    get itemsField(): PropertiesField;
    set itemsField(field: PropertiesField);
    isArrayPropertiesField(): this is ArrayPropertiesField;
    /** Get array item field if it matches the given name, or `undefined` if not. */
    getFieldByName(name: string): Field | undefined;
    clone(): ArrayPropertiesField;
    /**
     * Serialize this object to JSON.
     * @deprecated in 5.0 - might be removed in next major version. Use [[toCompressedJSON]] instead.
     */
    toJSON(): ArrayPropertiesFieldJSON;
    /** Serialize this object to compressed JSON */
    toCompressedJSON(classesMap: {
        [id: string]: CompressedClassInfoJSON;
    }): ArrayPropertiesFieldJSON<string>;
    /**
     * Deserialize [[ArrayPropertiesField]] from JSON.
     * @deprecated in 5.0 - might be removed in next major version. Use [[fromCompressedJSON]] instead.
     */
    static fromJSON(json: ArrayPropertiesFieldJSON, categories: CategoryDescription[]): ArrayPropertiesField;
    /**
     * Deserialize an [[ArrayPropertiesField]] from compressed JSON.
     * @public
     */
    static fromCompressedJSON(json: ArrayPropertiesFieldJSON<Id64String>, classesMap: {
        [id: string]: CompressedClassInfoJSON;
    }, categories: CategoryDescription[]): ArrayPropertiesField;
}
/**
 * Props for creating [[StructPropertiesField]].
 * @public
 */
interface StructPropertiesFieldProps extends PropertiesFieldProps {
    memberFields: PropertiesField[];
}
/**
 * Describes a content field that's based on one or more similar EC struct properties.
 * @public
 */
export declare class StructPropertiesField extends PropertiesField implements StructPropertiesFieldProps, IFieldsSource {
    #private;
    /**
     * Creates an instance of [[StructPropertiesField]].
     * @deprecated in 5.0 - might be removed in next major version. Use an overload with `StructPropertiesFieldProps` instead.
     */
    constructor(category: CategoryDescription, name: string, label: string, type: TypeDescription, memberFields: PropertiesField[], isReadonly: boolean, priority: number, properties: Property[], editor?: EditorDescription, renderer?: RendererDescription);
    /** Creates an instance of [[StructPropertiesField]]. */
    constructor(props: StructPropertiesFieldProps);
    /** Returns or sets the struct member fields. When setting, updates `parentStructField` of each member field to this field. */
    get memberFields(): PropertiesField[];
    set memberFields(fields: PropertiesField[]);
    isStructPropertiesField(): this is StructPropertiesField;
    /** Get a member field by its name. */
    getFieldByName(name: string): Field | undefined;
    clone(): StructPropertiesField;
    /**
     * Serialize this object to JSON.
     * @deprecated in 5.0 - might be removed in next major version. Use [[toCompressedJSON]] instead.
     */
    toJSON(): StructPropertiesFieldJSON;
    /** Serialize this object to compressed JSON */
    toCompressedJSON(classesMap: {
        [id: string]: CompressedClassInfoJSON;
    }): StructPropertiesFieldJSON<string>;
    /**
     * Deserialize [[StructPropertiesField]] from JSON.
     * @deprecated in 5.0 - might be removed in next major version. Use [[fromCompressedJSON]] instead.
     */
    static fromJSON(json: StructPropertiesFieldJSON, categories: CategoryDescription[]): StructPropertiesField;
    /**
     * Deserialize a [[StructPropertiesField]] from compressed JSON.
     * @public
     */
    static fromCompressedJSON(json: StructPropertiesFieldJSON<Id64String>, classesMap: {
        [id: string]: CompressedClassInfoJSON;
    }, categories: CategoryDescription[]): StructPropertiesField;
}
/**
 * Props for creating [[NestedContentField]].
 * @public
 */
interface NestedContentFieldProps extends FieldProps {
    /** Information about an ECClass whose properties are nested inside this field */
    contentClassInfo: ClassInfo;
    /** Relationship path to [Primary class]($docs/presentation/content/Terminology#primary-class) */
    pathToPrimaryClass: RelationshipPath;
    /**
     * Meaning of the relationship between the [primary class]($docs/presentation/content/Terminology#primary-class)
     * and content class of this field.
     *
     * The value is set up through [[RelatedPropertiesSpecification.relationshipMeaning]] attribute when setting up
     * presentation rules for creating the content.
     */
    relationshipMeaning?: RelationshipMeaning;
    /**
     * When content descriptor is requested in a polymorphic fashion, fields get created if at least one of the concrete classes
     * has it. In certain situations it's necessary to know which concrete classes caused that and this attribute is
     * here to help.
     *
     * **Example:** There's a base class `A` and it has two derived classes `B` and `C` and class `B` has a relationship to class `D`.
     * When content descriptor is requested for class `A` polymorphically, it's going to contain fields for all properties of class `B`,
     * class `C` and a nested content field for the `B -> D` relationship. The nested content field's `actualPrimaryClassIds` attribute
     * will contain ID of class `B`, identifying that only this specific class has the relationship.
     */
    actualPrimaryClassIds?: Id64String[];
    /** Contained nested fields */
    nestedFields: Field[];
    /** Flag specifying whether field should be expanded */
    autoExpand?: boolean;
}
/**
 * Describes a content field that contains [Nested content]($docs/presentation/content/Terminology#nested-content).
 *
 * @public
 */
export declare class NestedContentField extends Field implements NestedContentFieldProps, IFieldsSource {
    /** Information about an ECClass whose properties are nested inside this field */
    contentClassInfo: ClassInfo;
    /** Relationship path to [Primary class]($docs/presentation/content/Terminology#primary-class) */
    pathToPrimaryClass: RelationshipPath;
    /**
     * Meaning of the relationship between the [primary class]($docs/presentation/content/Terminology#primary-class)
     * and content class of this field.
     *
     * The value is set up through [[RelatedPropertiesSpecification.relationshipMeaning]] attribute when setting up
     * presentation rules for creating the content.
     */
    relationshipMeaning: RelationshipMeaning;
    /**
     * When content descriptor is requested in a polymorphic fashion, fields get created if at least one of the concrete classes
     * has it. In certain situations it's necessary to know which concrete classes caused that and this attribute is
     * here to help.
     *
     * **Example:** There's a base class `A` and it has two derived classes `B` and `C` and class `B` has a relationship to class `D`.
     * When content descriptor is requested for class `A` polymorphically, it's going to contain fields for all properties of class `B`,
     * class `C` and a nested content field for the `B -> D` relationship. The nested content field's `actualPrimaryClassIds` attribute
     * will contain ID of class `B`, identifying that only this specific class has the relationship.
     */
    actualPrimaryClassIds: Id64String[];
    /** Contained nested fields */
    nestedFields: Field[];
    /** Flag specifying whether field should be expanded */
    autoExpand?: boolean;
    /**
     * Creates an instance of [[NestedContentField]].
     * @param category Category information
     * @param name Unique name
     * @param label Display label
     * @param type Description of this field's values data type
     * @param isReadonly Are values in this field read-only
     * @param priority Priority of the field
     * @param contentClassInfo Information about an ECClass whose properties are nested inside this field
     * @param pathToPrimaryClass Relationship path to [Primary class]($docs/presentation/content/Terminology#primary-class)
     * @param nestedFields Contained nested fields
     * @param editor Property editor used to edit values of this field
     * @param autoExpand Flag specifying whether field should be expanded
     * @param relationshipMeaning RelationshipMeaning of the field
     * @param renderer Property renderer used to render values of this field
     * @deprecated in 5.0 - might be removed in next major version. Use an overload with `NestedContentFieldProps` instead.
     */
    constructor(category: CategoryDescription, name: string, label: string, type: TypeDescription, isReadonly: boolean, priority: number, contentClassInfo: ClassInfo, pathToPrimaryClass: RelationshipPath, nestedFields: Field[], editor?: EditorDescription, autoExpand?: boolean, renderer?: RendererDescription);
    /** Creates an instance of [[NestedContentField]]. */
    constructor(props: NestedContentFieldProps);
    clone(): NestedContentField;
    /**
     * Get field by its name
     * @param name Name of the field to find
     * @param recurse Recurse into nested fields
     */
    getFieldByName(name: string, recurse?: boolean): Field | undefined;
    /**
     * Serialize this object to JSON.
     * @deprecated in 5.0 - might be removed in next major version. Use [[toCompressedJSON]] instead.
     */
    toJSON(): NestedContentFieldJSON;
    /** Serialize this object to compressed JSON */
    toCompressedJSON(classesMap: {
        [id: string]: CompressedClassInfoJSON;
    }): NestedContentFieldJSON<string>;
    /** Deserialize a [[NestedContentField]] from compressed JSON. */
    static fromCompressedJSON(json: NestedContentFieldJSON<Id64String>, classesMap: {
        [id: string]: CompressedClassInfoJSON;
    }, categories: CategoryDescription[]): NestedContentField;
    /** Resets parent of this field and all nested fields. */
    resetParentship(): void;
    /**
     * Sets provided [[NestedContentField]] as parent of this fields and recursively updates
     * all nested fields parents.
     */
    rebuildParentship(parentField?: NestedContentField): void;
}
/** @internal */
export declare const getFieldByName: (fields: Field[], name: string | undefined, recurse?: boolean) => Field | undefined;
/** @internal */
export declare const getFieldByDescriptor: (fields: Field[], fieldDescriptor: FieldDescriptor, recurse?: boolean) => Field | undefined;
/**
 * Types of different field descriptors.
 * @public
 */
export declare enum FieldDescriptorType {
    Name = "name",
    Properties = "properties"
}
/**
 * Base for a field descriptor
 * @public
 */
export interface FieldDescriptorBase {
    type: FieldDescriptorType;
}
/**
 * A union of all possible field descriptor types
 * @public
 */
export type FieldDescriptor = NamedFieldDescriptor | PropertiesFieldDescriptor;
/** @public */
export declare namespace FieldDescriptor {
    /** Is this a named field descriptor */
    function isNamed(d: FieldDescriptor): d is NamedFieldDescriptor;
    /** Is this a properties field descriptor */
    function isProperties(d: FieldDescriptor): d is PropertiesFieldDescriptor;
}
/**
 * Field descriptor that identifies a content field by its unique name.
 * @public
 */
export interface NamedFieldDescriptor extends FieldDescriptorBase {
    type: FieldDescriptorType.Name;
    fieldName: string;
}
/**
 * Field descriptor that identifies a properties field using a list of
 * properties that the field contains.
 * @public
 */
export interface PropertiesFieldDescriptor extends FieldDescriptorBase {
    type: FieldDescriptorType.Properties;
    pathFromSelectToPropertyClass: StrippedRelationshipPath;
    /**
     * A list of properties that describe the field. At least one property in the list must
     * match at least one property in the field for the descriptor to be considered matching.
     */
    properties: Array<{
        /** Full class name */
        class: string;
        /** Property name */
        name: string;
    }>;
}
export {};
//# sourceMappingURL=Fields.d.ts.map