/** * External dependencies */ import type { ReactElement, ComponentType } from 'react'; /** * Utility type that makes all properties of T optional recursively. * Used by field setValue functions to allow partial item updates. */ export type DeepPartial = { [P in keyof T]?: T[P] extends object ? DeepPartial : T[P]; }; export type SortDirection = 'asc' | 'desc'; /** * Generic option type. */ export interface Option { value: Value; label: string; description?: string; } export interface FilterByConfig { /** * The list of operators supported by the field. */ operators?: Operator[]; /** * Whether it is a primary filter. * * A primary filter is always visible and is not listed in the "Add filter" component, * except for the list layout where it behaves like a secondary filter. */ isPrimary?: boolean; } export type Operator = 'is' | 'isNot' | 'isAny' | 'isNone' | 'isAll' | 'isNotAll' | 'lessThan' | 'greaterThan' | 'lessThanOrEqual' | 'greaterThanOrEqual' | 'before' | 'after' | 'beforeInc' | 'afterInc' | 'contains' | 'notContains' | 'startsWith' | 'between' | 'on' | 'notOn' | 'inThePast' | 'over'; export type FieldTypeName = 'text' | 'integer' | 'number' | 'datetime' | 'date' | 'media' | 'boolean' | 'email' | 'password' | 'telephone' | 'color' | 'url' | 'array'; export type Rules = { required?: boolean; elements?: boolean; pattern?: string; minLength?: number; maxLength?: number; min?: number; max?: number; custom?: ((item: Item, field: NormalizedField) => null | string) | ((item: Item, field: NormalizedField) => Promise); }; export type Validator = (item: Item, field: NormalizedField) => boolean; export type CustomValidator = ((item: Item, field: NormalizedField) => null | string) | ((item: Item, field: NormalizedField) => Promise); export type FilterOperator = (item: Item, field: NormalizedField, filterValue: any) => boolean; export type FilterOperatorMap = Partial>>; type NormalizedRule = { constraint: ConstraintType; validate: Validator; }; export type NormalizedRules = { required?: NormalizedRule; elements?: NormalizedRule; pattern?: NormalizedRule; minLength?: NormalizedRule; maxLength?: NormalizedRule; min?: NormalizedRule; max?: NormalizedRule; custom?: CustomValidator; }; /** * Edit configuration for textarea controls. */ export type EditConfigTextarea = { control: 'textarea'; /** * Number of rows for the textarea. */ rows?: number; }; /** * Edit configuration for text controls. */ export type EditConfigText = { control: 'text'; /** * Prefix component to display before the input. */ prefix?: React.ComponentType; /** * Suffix component to display after the input. */ suffix?: React.ComponentType; }; /** * Edit configuration for datetime controls. */ export type EditConfigDatetime = { control: 'datetime'; /** * Whether to render a compact version without the calendar widget. */ compact?: boolean; }; /** * Edit configuration for other control types (excluding 'text', 'textarea', and 'datetime'). */ export type EditConfigGeneric = { control: Exclude; }; /** * Edit configuration object with type-safe control options. * Each control type has its own specific configuration properties. */ export type EditConfig = EditConfigTextarea | EditConfigText | EditConfigDatetime | EditConfigGeneric; /** * A dataview field for a specific property of a data type. */ export type Field = { /** * Type of the fields. */ type?: FieldTypeName; /** * The unique identifier of the field. */ id: string; /** * The label of the field. Defaults to the id. */ label?: string; /** * The header of the field. Defaults to the label. * It allows the usage of a React Element to render the field labels. */ header?: string | ReactElement; /** * A description of the field. */ description?: string | ReactElement; /** * Placeholder for the field. */ placeholder?: string; /** * Callback used to render the field. Defaults to `field.getValue`. */ render?: ComponentType>; /** * Callback used to render an edit control for the field. */ Edit?: ComponentType> | string | EditConfig; /** * Callback used to sort the field. */ sort?: (a: Item, b: Item, direction: SortDirection) => number; /** * Callback used to validate the field. */ isValid?: Rules; /** * Callback used to decide if a field should be displayed. */ isVisible?: (item: Item) => boolean; /** * Whether the field is sortable. */ enableSorting?: boolean; /** * Whether the field is searchable. */ enableGlobalSearch?: boolean; /** * Whether the field can be hidden in the UI. */ enableHiding?: boolean; /** * The list of options to pick from when using the field as a filter. */ elements?: Option[]; /** * Retrieval function for elements. */ getElements?: () => Promise; /** * Filter config for the field. */ filterBy?: FilterByConfig | false; /** * Whether the field is readOnly. * If `true`, the value will be rendered using the `render` callback. */ readOnly?: boolean; /** * Callback used to retrieve the value of the field from the item. * Defaults to `item[ field.id ]`. */ getValue?: (args: { item: Item; }) => any; /** * Callback used to set the value of the field on the item. * Used for editing operations to update field values. */ setValue?: (args: { item: Item; value: any; }) => DeepPartial; /** * Display format configuration for fields. */ format?: FormatDatetime | FormatDate | FormatNumber | FormatInteger; /** * Callback used to format the value of the field for display. */ getValueFormatted?: ({ item, field, }: { item: Item; field: NormalizedField; }) => string; }; /** * Format for datetime fields: * * - datetime: the format string (e.g., "M j, Y g:i a" for "Jan 1, 2021 2:30 pm"). * - weekStartsOn: to specify the first day of the week (0 for 'sunday', 1 for 'monday', etc.). * * If not provided, defaults to WordPress date format settings. */ export type FormatDatetime = { datetime?: string; weekStartsOn?: DayNumber; }; /** * Format for date fields: * * - date: the format string (e.g., 'F j, Y' for 'March 10, 2023') * - weekStartsOn: to specify the first day of the week (0 for 'sunday', 1 for 'monday', etc.). * * If not provided, defaults to WordPress date format settings. */ export type FormatDate = { date?: string; weekStartsOn?: DayNumber; }; export type DayNumber = 0 | 1 | 2 | 3 | 4 | 5 | 6; /** * Format for number fields: * * - separatorThousand: character to use for thousand separators (e.g., ',') * - separatorDecimal: character to use for decimal point (e.g., '.') * - decimals: number of decimal places to display (e.g., 2) * * If not provided, defaults to ',' for thousands, '.' for decimal, 2 decimals. */ export type FormatNumber = { separatorThousand?: string; separatorDecimal?: string; decimals?: number; }; /** * Format for integer fields: * * - separatorThousand: character to use for thousand separators (e.g., ',') * * If not provided, defaults to ',' for thousands. */ export type FormatInteger = { separatorThousand?: string; }; export type NormalizedField = Omit, 'Edit' | 'isValid'> & { label: string; header: string | ReactElement; getValue: (args: { item: Item; }) => any; setValue: (args: { item: Item; value: any; }) => DeepPartial; render: ComponentType>; Edit: ComponentType> | null; hasElements: boolean; sort: (a: Item, b: Item, direction: SortDirection) => number; isValid: NormalizedRules; enableHiding: boolean; enableSorting: boolean; filterBy: Required | false; filter: FilterOperatorMap; readOnly: boolean; format: {} | Required | Required | Required; getValueFormatted: ({ item, field, }: { item: Item; field: NormalizedField; }) => string; }; /** * A collection of dataview fields for a data type. */ export type Fields = Field[]; export type FieldValidity = { required?: { type: 'valid' | 'invalid' | 'validating'; message?: string; }; pattern?: { type: 'valid' | 'invalid' | 'validating'; message: string; }; min?: { type: 'valid' | 'invalid' | 'validating'; message: string; }; max?: { type: 'valid' | 'invalid' | 'validating'; message: string; }; minLength?: { type: 'valid' | 'invalid' | 'validating'; message: string; }; maxLength?: { type: 'valid' | 'invalid' | 'validating'; message: string; }; elements?: { type: 'valid' | 'invalid' | 'validating'; message: string; }; custom?: { type: 'valid' | 'invalid' | 'validating'; message: string; }; children?: Record; }; export type DataFormControlProps = { data: Item; field: NormalizedField; onChange: (value: DeepPartial) => void; hideLabelFromVision?: boolean; /** * Label the control as "optional" when _not_ required, instead of showing "required". */ markWhenOptional?: boolean; /** * The currently selected filter operator for this field. * * Used by DataViews filters to determine which control to render based on the operator type. */ operator?: Operator; /** * Validity information for the field, if any. */ validity?: FieldValidity; /** * Configuration object for the control. */ config?: { prefix?: React.ComponentType; suffix?: React.ComponentType; rows?: number; compact?: boolean; }; }; export type DataViewRenderFieldProps = { item: Item; field: NormalizedField; config?: { sizes: string; }; }; export {}; //# sourceMappingURL=field-api.d.ts.map