fix: passes field permissions to custom fields (#10024)
Fixes #9888. Field permissions were not being passed into custom components. This led to custom components, such as arrays and blocks, unable to render default Payload fields. This was because their props lacked the permissions object required for rendering. For example: ```ts 'use client' import type { ArrayFieldClientComponent } from 'payload' import { ArrayField } from '@payloadcms/ui' export const MyArray: ArrayFieldClientComponent = (props) => <ArrayField {...props} /> ``` In this example the array field itself would render, but the fields within each row would not, because the array field did not pass its permissions down to the rows.
This commit is contained in:
@@ -21,8 +21,7 @@ type ArrayFieldClientWithoutType = MarkOptional<ArrayFieldClient, 'type'>
|
||||
|
||||
type ArrayFieldBaseClientProps = {
|
||||
readonly validate?: ArrayFieldValidation
|
||||
} & FieldPaths &
|
||||
Pick<ServerFieldBase, 'permissions'>
|
||||
} & FieldPaths
|
||||
|
||||
export type ArrayFieldClientProps = ArrayFieldBaseClientProps &
|
||||
ClientFieldBase<ArrayFieldClientWithoutType>
|
||||
|
||||
@@ -21,8 +21,7 @@ type BlocksFieldClientWithoutType = MarkOptional<BlocksFieldClient, 'type'>
|
||||
|
||||
type BlocksFieldBaseClientProps = {
|
||||
readonly validate?: BlocksFieldValidation
|
||||
} & FieldPaths &
|
||||
Pick<ServerFieldBase, 'permissions'>
|
||||
} & FieldPaths
|
||||
|
||||
export type BlocksFieldClientProps = BlocksFieldBaseClientProps &
|
||||
ClientFieldBase<BlocksFieldClientWithoutType>
|
||||
|
||||
@@ -16,7 +16,7 @@ import type {
|
||||
FieldLabelServerComponent,
|
||||
} from '../types.js'
|
||||
|
||||
type CollapsibleFieldBaseClientProps = FieldPaths & Pick<ServerFieldBase, 'permissions'>
|
||||
type CollapsibleFieldBaseClientProps = FieldPaths
|
||||
|
||||
type CollapsibleFieldClientWithoutType = MarkOptional<CollapsibleFieldClient, 'type'>
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import type {
|
||||
|
||||
type GroupFieldClientWithoutType = MarkOptional<GroupFieldClient, 'type'>
|
||||
|
||||
export type GroupFieldBaseClientProps = FieldPaths & Pick<ServerFieldBase, 'permissions'>
|
||||
export type GroupFieldBaseClientProps = FieldPaths
|
||||
|
||||
export type GroupFieldClientProps = ClientFieldBase<GroupFieldClientWithoutType> &
|
||||
GroupFieldBaseClientProps
|
||||
|
||||
@@ -21,8 +21,7 @@ type RowFieldClientWithoutType = MarkOptional<RowFieldClient, 'type'>
|
||||
|
||||
type RowFieldBaseClientProps = {
|
||||
readonly forceRender?: boolean
|
||||
} & Omit<FieldPaths, 'path'> &
|
||||
Pick<ServerFieldBase, 'permissions'>
|
||||
} & Omit<FieldPaths, 'path'>
|
||||
|
||||
export type RowFieldClientProps = Omit<ClientFieldBase<RowFieldClientWithoutType>, 'path'> &
|
||||
RowFieldBaseClientProps
|
||||
|
||||
@@ -26,7 +26,7 @@ export type ClientTab =
|
||||
| ({ fields: ClientField[]; readonly path?: string } & Omit<NamedTab, 'fields'>)
|
||||
| ({ fields: ClientField[] } & Omit<UnnamedTab, 'fields'>)
|
||||
|
||||
type TabsFieldBaseClientProps = FieldPaths & Pick<ServerFieldBase, 'permissions'>
|
||||
type TabsFieldBaseClientProps = FieldPaths
|
||||
|
||||
type TabsFieldClientWithoutType = MarkOptional<TabsFieldClient, 'type'>
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ export type ClientComponentProps = {
|
||||
customComponents: FormField['customComponents']
|
||||
field: ClientBlock | ClientField | ClientTab
|
||||
forceRender?: boolean
|
||||
permissions?: SanitizedFieldPermissions
|
||||
readOnly?: boolean
|
||||
renderedBlocks?: RenderedField[]
|
||||
/**
|
||||
|
||||
@@ -57,8 +57,12 @@ export function RenderField({
|
||||
return CustomField || null
|
||||
}
|
||||
|
||||
const baseFieldProps: Pick<ClientComponentProps, 'forceRender' | 'readOnly' | 'schemaPath'> = {
|
||||
const baseFieldProps: Pick<
|
||||
ClientComponentProps,
|
||||
'forceRender' | 'permissions' | 'readOnly' | 'schemaPath'
|
||||
> = {
|
||||
forceRender,
|
||||
permissions,
|
||||
readOnly,
|
||||
schemaPath,
|
||||
}
|
||||
@@ -68,7 +72,6 @@ export function RenderField({
|
||||
indexPath,
|
||||
parentPath,
|
||||
parentSchemaPath,
|
||||
permissions,
|
||||
}
|
||||
|
||||
if (clientFieldConfig.admin?.hidden) {
|
||||
|
||||
@@ -55,6 +55,7 @@ export const renderField: RenderFieldMethod = ({
|
||||
customComponents: fieldState?.customComponents || {},
|
||||
field: clientField,
|
||||
path,
|
||||
permissions,
|
||||
readOnly: typeof permissions === 'boolean' ? !permissions : !permissions?.[operation],
|
||||
schemaPath,
|
||||
}
|
||||
|
||||
12
test/fields/collections/Array/CustomArrayField.tsx
Normal file
12
test/fields/collections/Array/CustomArrayField.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
'use client'
|
||||
import type { ArrayFieldClientComponent } from 'payload'
|
||||
|
||||
import { ArrayField } from '@payloadcms/ui'
|
||||
|
||||
export const CustomArrayField: ArrayFieldClientComponent = (props) => {
|
||||
return (
|
||||
<div id="custom-array-field">
|
||||
<ArrayField {...props} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -2,9 +2,9 @@ import type { TextFieldServerComponent } from 'payload'
|
||||
|
||||
import { TextField } from '@payloadcms/ui'
|
||||
|
||||
export const CustomField: TextFieldServerComponent = ({ clientField, path }) => {
|
||||
export const CustomTextField: TextFieldServerComponent = ({ clientField, path }) => {
|
||||
return (
|
||||
<div id="custom-field">
|
||||
<div id="custom-text-field">
|
||||
<TextField field={clientField} path={path as string} />
|
||||
</div>
|
||||
)
|
||||
@@ -106,6 +106,12 @@ describe('Array', () => {
|
||||
await expect(customRowLabel).toHaveCSS('text-transform', 'uppercase')
|
||||
})
|
||||
|
||||
test('should render default array field within custom component', async () => {
|
||||
await page.goto(url.create)
|
||||
await page.locator('#field-customArrayField >> .array-field__add-row').click()
|
||||
await expect(page.locator('#field-customArrayField__0__text')).toBeVisible()
|
||||
})
|
||||
|
||||
// eslint-disable-next-line playwright/expect-expect
|
||||
test('should bypass min rows validation when no rows present and field is not required', async () => {
|
||||
await page.goto(url.create)
|
||||
@@ -313,7 +319,7 @@ describe('Array', () => {
|
||||
test('should externally update array rows and render custom fields', async () => {
|
||||
await page.goto(url.create)
|
||||
await page.locator('#updateArrayExternally').click()
|
||||
await expect(page.locator('#custom-field')).toBeVisible()
|
||||
await expect(page.locator('#custom-text-field')).toBeVisible()
|
||||
})
|
||||
|
||||
test('should not re-close initCollapsed true array rows on input in create new view', async () => {
|
||||
|
||||
@@ -194,16 +194,31 @@ const ArrayFields: CollectionConfig = {
|
||||
type: 'array',
|
||||
fields: [
|
||||
{
|
||||
name: 'customField',
|
||||
name: 'customTextField',
|
||||
type: 'ui',
|
||||
admin: {
|
||||
components: {
|
||||
Field: '/collections/Array/CustomField.js#CustomField',
|
||||
Field: '/collections/Array/CustomTextField.js#CustomTextField',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'customArrayField',
|
||||
type: 'array',
|
||||
admin: {
|
||||
components: {
|
||||
Field: '/collections/Array/CustomArrayField.js#CustomArrayField',
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'ui',
|
||||
type: 'ui',
|
||||
|
||||
@@ -505,6 +505,12 @@ export interface ArrayField {
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
customArrayField?:
|
||||
| {
|
||||
text?: string | null;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
@@ -2060,6 +2066,12 @@ export interface ArrayFieldsSelect<T extends boolean = true> {
|
||||
| {
|
||||
id?: T;
|
||||
};
|
||||
customArrayField?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
};
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
@@ -2071,257 +2083,42 @@ export interface BlockFieldsSelect<T extends boolean = true> {
|
||||
blocks?:
|
||||
| T
|
||||
| {
|
||||
content?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
richText?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
text?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
tabs?:
|
||||
| T
|
||||
| {
|
||||
textInCollapsible?: T;
|
||||
textInRow?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
content?: T | ContentBlockSelect<T>;
|
||||
number?: T | NumberBlockSelect<T>;
|
||||
subBlocks?: T | SubBlocksBlockSelect<T>;
|
||||
tabs?: T | TabsBlockSelect<T>;
|
||||
};
|
||||
duplicate?:
|
||||
| T
|
||||
| {
|
||||
content?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
richText?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
text?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
tabs?:
|
||||
| T
|
||||
| {
|
||||
textInCollapsible?: T;
|
||||
textInRow?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
content?: T | ContentBlockSelect<T>;
|
||||
number?: T | NumberBlockSelect<T>;
|
||||
subBlocks?: T | SubBlocksBlockSelect<T>;
|
||||
tabs?: T | TabsBlockSelect<T>;
|
||||
};
|
||||
collapsedByDefaultBlocks?:
|
||||
| T
|
||||
| {
|
||||
localizedContent?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
richText?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedNumber?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedSubBlocks?:
|
||||
| T
|
||||
| {
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
text?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedTabs?:
|
||||
| T
|
||||
| {
|
||||
textInCollapsible?: T;
|
||||
textInRow?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedContent?: T | LocalizedContentBlockSelect<T>;
|
||||
localizedNumber?: T | LocalizedNumberBlockSelect<T>;
|
||||
localizedSubBlocks?: T | LocalizedSubBlocksBlockSelect<T>;
|
||||
localizedTabs?: T | LocalizedTabsBlockSelect<T>;
|
||||
};
|
||||
disableSort?:
|
||||
| T
|
||||
| {
|
||||
localizedContent?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
richText?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedNumber?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedSubBlocks?:
|
||||
| T
|
||||
| {
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
text?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedTabs?:
|
||||
| T
|
||||
| {
|
||||
textInCollapsible?: T;
|
||||
textInRow?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedContent?: T | LocalizedContentBlockSelect<T>;
|
||||
localizedNumber?: T | LocalizedNumberBlockSelect<T>;
|
||||
localizedSubBlocks?: T | LocalizedSubBlocksBlockSelect<T>;
|
||||
localizedTabs?: T | LocalizedTabsBlockSelect<T>;
|
||||
};
|
||||
localizedBlocks?:
|
||||
| T
|
||||
| {
|
||||
localizedContent?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
richText?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedNumber?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedSubBlocks?:
|
||||
| T
|
||||
| {
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
text?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedTabs?:
|
||||
| T
|
||||
| {
|
||||
textInCollapsible?: T;
|
||||
textInRow?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
localizedContent?: T | LocalizedContentBlockSelect<T>;
|
||||
localizedNumber?: T | LocalizedNumberBlockSelect<T>;
|
||||
localizedSubBlocks?: T | LocalizedSubBlocksBlockSelect<T>;
|
||||
localizedTabs?: T | LocalizedTabsBlockSelect<T>;
|
||||
};
|
||||
i18nBlocks?:
|
||||
| T
|
||||
@@ -2459,6 +2256,116 @@ export interface BlockFieldsSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "ContentBlock_select".
|
||||
*/
|
||||
export interface ContentBlockSelect<T extends boolean = true> {
|
||||
text?: T;
|
||||
richText?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "NumberBlock_select".
|
||||
*/
|
||||
export interface NumberBlockSelect<T extends boolean = true> {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "SubBlocksBlock_select".
|
||||
*/
|
||||
export interface SubBlocksBlockSelect<T extends boolean = true> {
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
text?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "TabsBlock_select".
|
||||
*/
|
||||
export interface TabsBlockSelect<T extends boolean = true> {
|
||||
textInCollapsible?: T;
|
||||
textInRow?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "localizedContentBlock_select".
|
||||
*/
|
||||
export interface LocalizedContentBlockSelect<T extends boolean = true> {
|
||||
text?: T;
|
||||
richText?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "localizedNumberBlock_select".
|
||||
*/
|
||||
export interface LocalizedNumberBlockSelect<T extends boolean = true> {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "localizedSubBlocksBlock_select".
|
||||
*/
|
||||
export interface LocalizedSubBlocksBlockSelect<T extends boolean = true> {
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
text?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "localizedTabsBlock_select".
|
||||
*/
|
||||
export interface LocalizedTabsBlockSelect<T extends boolean = true> {
|
||||
textInCollapsible?: T;
|
||||
textInRow?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "checkbox-fields_select".
|
||||
@@ -3021,53 +2928,10 @@ export interface TabsFieldsSelect<T extends boolean = true> {
|
||||
blocks?:
|
||||
| T
|
||||
| {
|
||||
content?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
richText?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
subBlocks?:
|
||||
| T
|
||||
| {
|
||||
text?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
number?:
|
||||
| T
|
||||
| {
|
||||
number?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
tabs?:
|
||||
| T
|
||||
| {
|
||||
textInCollapsible?: T;
|
||||
textInRow?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
content?: T | ContentBlockSelect<T>;
|
||||
number?: T | NumberBlockSelect<T>;
|
||||
subBlocks?: T | SubBlocksBlockSelect<T>;
|
||||
tabs?: T | TabsBlockSelect<T>;
|
||||
};
|
||||
group?:
|
||||
| T
|
||||
@@ -3077,24 +2941,7 @@ export interface TabsFieldsSelect<T extends boolean = true> {
|
||||
textInRow?: T;
|
||||
numberInRow?: T;
|
||||
json?: T;
|
||||
tab?:
|
||||
| T
|
||||
| {
|
||||
array?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
};
|
||||
text?: T;
|
||||
defaultValue?: T;
|
||||
arrayInRow?:
|
||||
| T
|
||||
| {
|
||||
textInArrayInRow?: T;
|
||||
id?: T;
|
||||
};
|
||||
};
|
||||
tab?: T | TabWithNameSelect<T>;
|
||||
namedTabWithDefaultValue?:
|
||||
| T
|
||||
| {
|
||||
@@ -3144,6 +2991,26 @@ export interface TabsFieldsSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "TabWithName_select".
|
||||
*/
|
||||
export interface TabWithNameSelect<T extends boolean = true> {
|
||||
array?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
};
|
||||
text?: T;
|
||||
defaultValue?: T;
|
||||
arrayInRow?:
|
||||
| T
|
||||
| {
|
||||
textInArrayInRow?: T;
|
||||
id?: T;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "text-fields_select".
|
||||
|
||||
Reference in New Issue
Block a user