Deposit Form Components
This page documents the available form components for customizing record deposit forms. For field metadata and the useFieldData hook, see Deposit form. For search result components, see Search result components.
Basic Components
TextField
Standard text input component from oarepo-ui with automatic field metadata integration:
import { TextField } from "@js/oarepo_ui/forms";
<TextField fieldPath="metadata.title" />Automatically applies field metadata from your model YAML, XSS protection, and Formik integration.
Source: oarepo-ui/forms/components/TextField
Based on: react-invenio-forms.TextField
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
fieldPath | string | (required) | Dot-separated path to field in form state |
fieldRepresentation | string | "full" | Label display mode passed to useFieldData: "full", "compact", "text" |
icon | string | "pencil" | Icon to display with field (passed to useFieldData) |
optimized | boolean | true | Use FastField for performance (only re-renders this field) |
StringArrayField
Array of text inputs with add/remove functionality:
import { StringArrayField } from "@js/oarepo_ui/forms";
<StringArrayField
fieldPath="metadata.keywords"
addButtonLabel="Add keyword"
/>Source: oarepo-ui/forms/components/StringArrayField
Based on: react-invenio-forms.ArrayField
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
fieldPath | string | (required) | Formik path to the array value |
label | string | node | null | Label displayed above the field |
required | boolean | false | Marks the field as required |
defaultNewValue | string | "" | Value inserted when a new element is added |
addButtonLabel | string | node | (i18n) | Text shown on the “Add” button |
helpText | string | "" | Supplemental description rendered below inputs |
labelIcon | string | "" | Icon name displayed next to the label |
showEmptyValue | boolean | false | Auto-add empty entry on first render |
icon | string | null | Icon passed to field data wrapper |
fieldRepresentation | string | "text" | Field representation mode for useFieldData |
Date Fields
Extended Date/Time Format (EDTF) compliant date pickers:
import {
EDTFSingleDatePickerField,
EDTFDateRangePickerField,
} from "@js/oarepo_ui/forms";
// Single date
<EDTFSingleDatePickerField fieldPath="metadata.publication_date" />
// Date range with single/range toggle
<EDTFDateRangePickerField fieldPath="metadata.date_range" />Source: oarepo-ui/forms/components/EDTFDatePickerField
Based on: Formik useField, react-datepicker
EDTFSingleDatePickerField
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
fieldPath | string | (required) | Path to the field in Formik form state |
label | string | node | from schema | Field label |
helpText | string | from schema | Helper text below the input |
required | boolean | false | Marks field as required |
placeholder | string | from schema | Placeholder shown when no date selected |
datePickerProps | object | {} | Props forwarded to underlying date-picker |
customInputProps | object | {} | Props passed to custom input element |
icon | string | "calendar" | Icon displayed next to label |
EDTFDateRangePickerField
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
fieldPath | string | (required) | Path to the field in Formik form state |
label | string | node | from schema | Field label |
icon | string | "calendar" | Icon displayed next to label |
helpText | string | from schema | Helper text below the input |
required | boolean | false | Marks field as required |
dateRangeInputPlaceholder | string | (i18n) | Placeholder for range mode |
singleDateInputPlaceholder | string | (i18n) | Placeholder for single date mode |
datePickerPropsOverrides | object | {} | Override underlying date-picker props |
I18n Fields
I18nTextInputField
Internationalized text field with language selector:
import { I18nTextInputField } from "@js/oarepo_ui/forms";
<I18nTextInputField
fieldPath="metadata.title"
usedLanguages={["en", "cs"]}
lngFieldWidth={3}
/>Source: oarepo-ui/forms/components/I18nTextInputField
Based on: react-invenio-forms.GroupField, react-invenio-forms.TextField, oarepo-ui.LanguageSelectField
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
fieldPath | string | (required) | Base path for the multilingual value |
optimized | boolean | true | Use optimized rendering mode |
lngFieldWidth | number | 3 | Width of language selector (columns) |
usedLanguages | array | [] | Already used language codes to exclude |
I18nRichInputField
Internationalized rich text editor:
import { I18nRichInputField } from "@js/oarepo_ui/forms";
<I18nRichInputField
fieldPath="metadata.description"
editorConfig={{ minHeight: 150 }}
/>Source: oarepo-ui/forms/components/I18nRichInputField
Based on: react-invenio-forms.RichInputField, react-invenio-forms.GroupField, oarepo-ui.OarepoRichEditor
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
fieldPath | string | (required) | Base path for the multilingual field |
optimized | boolean | true | Enable form-level optimizations |
editorConfig | object | {} | Configuration for rich-text editor |
lngFieldWidth | number | 3 | Width of language selector (columns) |
usedLanguages | array | [] | Already used language codes to exclude |
MultilingualTextInput
Wrapper for multiple language entries with automatic language management:
import { MultilingualTextInput } from "@js/oarepo_ui/forms";
<MultilingualTextInput
fieldPath="metadata.titles"
rich={false}
addButtonLabel="Add another language"
showEmptyValue={true}
/>Source: oarepo-ui/forms/components/MultilingualTextInput
Based on: react-invenio-forms.ArrayField, oarepo-ui.I18nTextInputField, oarepo-ui.I18nRichInputField
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
fieldPath | string | (required) | Path to the form field |
labelIcon | string | null | Icon name for field label |
defaultNewValue | object | {lang:"", value:""} | Default for new language entry |
rich | boolean | false | Use rich-text editor instead of plain text |
addButtonLabel | string | (i18n) | Label for “add language” button |
lngFieldWidth | number | (from config) | Width of language selector |
showEmptyValue | boolean | false | Show empty input when no values |
prefillLanguageWithDefaultLocale | boolean | false | Prefill new language with default locale |
removeButtonLabelClassName | string | "" | CSS class for remove button label |
displayFirstInputRemoveButton | boolean | true | Show remove button on first input |
LanguageSelectField
Language selection dropdown with search and filtering:
import { LanguageSelectField } from "@js/oarepo_ui/forms";
<LanguageSelectField
fieldPath="metadata.language"
usedLanguages={["en"]}
/>Source: oarepo-ui/forms/components/LanguageSelectField
Based on: react-invenio-forms.SelectField
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
fieldPath | string | (required) | Path to the field in Formik values |
label | string | node | (i18n) | Field label |
labelIcon | string | "globe" | Icon name for label |
required | boolean | false | Marks field as required |
placeholder | string | (i18n) | Placeholder text |
clearable | boolean | true | Allow clearing selection |
usedLanguages | array | [] | Already used languages (hidden unless selected) |
Person/Contributor Fields
CreatibutorsField
Array field for creators/contributors with drag-and-drop reordering and modal editor:
import { CreatibutorsField } from "@js/oarepo_ui/forms";
<CreatibutorsField
fieldPath="metadata.creators"
schema="creators"
showRoleField={true}
/>Source: oarepo-ui/forms/components/CreatibutorsField
Based on: react-invenio-forms.FieldArray, react-dnd
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
fieldPath | string | (required) | Path to store the array |
schema | "creators" | "contributors" | (required) | Type of field (affects labels) |
label | string | (i18n) | Field label |
icon | string | "user" | Icon for field label |
showRoleField | boolean | false | Show role selector for each item |
required | boolean | false | Marks field as required |
addButtonLabel | string | (i18n) | Text for “Add” button |
modal | object | (i18n) | Override modal labels {addLabel, editLabel} |
autocompleteNames | "search" | "search_only" | "off" | "search" | Name autocomplete behavior |
roleOptions | array | (from config) | Options for role dropdown |
Role options are typically loaded from form config at vocabularies.contributor-types.
IdentifiersField
Array of identifier type-value pairs with validation:
import {
IdentifiersField,
personIdentifiersSchema,
objectIdentifiersSchema,
organizationIdentifiersSchema,
} from "@js/oarepo_ui/forms";
<IdentifiersField
fieldPath="metadata.identifiers"
options={personIdentifiersSchema}
/>Source: oarepo-ui/forms/components/IdentifiersField
Based on: react-invenio-forms.ArrayField, react-invenio-forms.SelectField, react-invenio-forms.TextField
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
fieldPath | string | (required) | Path to identifiers array |
options | array | (required) | Choices for scheme dropdown |
labelIcon | string | "pencil" | Icon beside field label |
className | string | "" | Additional CSS class |
defaultNewValue | object | {scheme:"", identifier:""} | Template for new entry |
validateOnBlur | boolean | false | Run validation on blur |
Predefined option schemas:
personIdentifiersSchema- ORCID, ScopusID, ResearcherID, ISNI, etc.organizationIdentifiersSchema- ISNI, ROR, ICO, DOIobjectIdentifiersSchema- DOI, Handle, ISBN, ISSN, RIV
File Upload Components
InvenioRDM provides two file upload UI options:
| UI | When Used |
|---|---|
| FileUploader | APP_RDM_DEPOSIT_NG_FILES_UI_ENABLED = False |
| UppyUploader | APP_RDM_DEPOSIT_NG_FILES_UI_ENABLED = True (enable in invenio.cfg) |
Note: The nrp-model-copier template uses UppyUploader by default in FormFieldsContainer.jsx. To use the standard uploader used by InvenioRDM, import FileUploader instead.
CSP Configuration: When using Uppy, add to your application configuration (invenio.cfg):
APP_DEFAULT_SECURE_HEADERS = {
# ...
"script-src": ["'self'", "blob:", "'wasm-unsafe-eval'"],
# ...
}FileUploader (InvenioRDM default)
Simple, robust file picker and drag-and-drop UI with file list and progress indicators:
import { FileUploader } from "@js/invenio_rdm_records";
<FileUploader
config={formConfig}
files={files}
isDraftRecord={!record.is_published}
hasParentRecord={record?.versions?.index > 1}
quota={formConfig.quota}
permissions={permissions}
record={record}
uploadFiles={handleUpload}
deleteFile={handleDelete}
importParentFiles={handleImport}
decimalSizeDisplay={formConfig.decimal_size_display}
filesLocked={filesLocked}
allowEmptyFiles={formConfig.allow_empty_files}
fileModification={fileModification}
/>Source: invenio-rdm-records/fields/FileUploader
Props:
| Prop | Type | Required | Description |
|---|---|---|---|
config | object | no | UI configuration or overrides |
dragText | string | (i18n) | Text shown in drop-zone when dragging files |
files | object | no | Map of file identifiers → file metadata |
isDraftRecord | boolean | yes | true when editing a draft |
hasParentRecord | boolean | yes | Whether previous version exists (for import) |
quota | object | yes | {maxStorage, maxFiles} limits |
record | object | no | Full record object |
uploadButtonIcon | string | "upload" | Icon for upload button |
uploadButtonText | string | (i18n) | Upload button label |
importButtonIcon | string | "sync" | Icon for import button |
importButtonText | string | (i18n) | Import button label |
isFileImportInProgress | boolean | no | Loading state during import |
importParentFiles | func | yes | Callback to import files from parent |
uploadFiles | func | yes | Callback to upload files: (draft, files[]) => void |
deleteFile | func | yes | Callback to delete a file |
decimalSizeDisplay | boolean | yes | Show file sizes with decimal units |
filesLocked | boolean | yes | Disable drop-zone (after publish) |
permissions | object | no | Permission flags (can_new_version, etc.) |
allowEmptyFiles | boolean | yes | Allow zero-byte files |
fileModification | object | no | File modification settings for published records |
Features:
- Drag-and-drop or file picker
- File list with size and delete option
- Progress indicators for uploads
- Import files from previous version
- Warning for duplicate/empty files
- Quota enforcement (max files, max storage)
UppyUploader (Experimental)
Modern UI with folder upload, chunked upload, media preview, extensible plugins:
import { UppyUploader } from "@js/invenio_rdm_records";
<UppyUploader
isDraftRecord={!record.is_published}
config={formConfig}
quota={formConfig.quota}
decimalSizeDisplay={formConfig.decimal_size_display}
allowEmptyFiles={formConfig.allow_empty_files}
fileUploadConcurrency={formConfig.file_upload_concurrency}
showMetadataOnlyToggle={false}
filesLocked={filesLocked}
/>Source: invenio-rdm-records/fields/UppyUploader
Documentation: File Uploads - Uploader
Based on: Uppy.js library
Props:
| Prop | Type | Required | Description |
|---|---|---|---|
isDraftRecord | boolean | yes | Whether current record is a draft (allows uploads) |
config | object | yes | Form configuration object from deposit form |
quota | object | yes | Upload quota limits and remaining space |
decimalSizeDisplay | boolean | (from config) | Show file sizes with decimal or whole numbers |
allowEmptyFiles | boolean | (from config) | Allow uploading empty files |
fileUploadConcurrency | number | (from config) | Number of concurrent file uploads |
showMetadataOnlyToggle | boolean | false | Show metadata-only file toggle |
filesLocked | boolean | yes | Whether file uploads are disabled (published records) |
Features:
- Drag-and-drop or picker for files/folders
- Folder upload (entire directories at once)
- Chunked/multipart upload for large files
- Automatic retry on upload failure
- Per-part checksum validation
- Image previews and basic editing (crop, rotate, resize)
- Plugin system for extensions (validation, metadata, external sources)
- Mobile-responsive with keyboard navigation and screen-reader support |
AccessRightField
Record access and file permissions configuration:
import { AccessRightField } from "@js/oarepo_ui/forms";
<AccessRightField
fieldPath="access"
label="Access rights"
labelIcon="unlock"
record={record}
recordRestrictionGracePeriod={180}
allowRecordRestriction={true}
/>Source: oarepo-ui/forms/components/AccessRightField
Based on: invenio-rdm-records.AccessRightFieldCmp
Props:
| Prop | Type | Required | Description |
|---|---|---|---|
fieldPath | string | yes | Path to access-right field |
label | string | yes | Display label |
labelIcon | string | yes | Semantic UI icon name |
showMetadataAccess | bool | no | Show metadata access option (true) |
community | object | no | Specific community object |
record | object | yes | Current record object |
recordRestrictionGracePeriod | number | yes | Grace period in days |
allowRecordRestriction | bool | yes | Enable record restriction UI |
ArrayFieldItem
Helper component for rendering array items with remove button:
import { ArrayFieldItem } from "@js/oarepo_ui/forms";
<ArrayFieldItem
indexPath={index}
arrayHelpers={arrayHelpers}
fieldPathPrefix={`${fieldPath}.${index}`}
>
{/* Subfields */}
</ArrayFieldItem>Source: oarepo-ui/forms/components/ArrayFieldItem
Based on: react-invenio-forms.GroupField
Props:
| Prop | Type | Required | Description |
|---|---|---|---|
arrayHelpers | object | yes | Formik FieldArray helpers |
indexPath | number | yes | Index of this item in array |
fieldPathPrefix | string | yes | Prefix for button IDs |
children | node | no | JSX to render inside |
className | string | "invenio-group-field" | CSS class for GroupField |
removeButton | func | no | Custom remove button component |
removeButtonProps | object | no | Props for custom remove button |
displayFirstInputRemoveButton | boolean | true | Show remove on first element |
removeButtonLabelClassName | string | "" | Additional class for label |
Controlled Vocabulary Components
Components from oarepo-vocabularies for vocabulary term forms:
VocabularyField
Smart wrapper that automatically selects between local or API-loaded vocabulary selector based on form configuration:
import { VocabularyField } from "@js/oarepo_vocabularies_ui/form";
<VocabularyField
fieldPath="props.resource_type"
vocabularyName="resource_type"
/>Source: oarepo-vocabularies/VocabularyField
Based on: LocalVocabularySelectField or VocabularySelectField (auto-selected)
Props:
| Prop | Type | Required | Description |
|---|---|---|---|
fieldPath | string | yes | Path to field in Formik values |
vocabularyName | string | yes | Vocabulary identifier |
VocabularySelectField
API-loaded vocabulary selector for large vocabularies with pagination and remote search:
import { VocabularySelectField } from "@js/oarepo_vocabularies_ui/form";
<VocabularySelectField
vocabularyName="languages"
fieldPath="props.language"
multiple={false}
showLeafsOnly={false}
/>Source: oarepo-vocabularies/VocabularySelectField
Based on: react-invenio-forms.RemoteSelectField
Props:
| Prop | Type | Required | Description |
|---|---|---|---|
vocabularyName | string | yes | Vocabulary identifier (/api/vocabularies/<name>) |
fieldPath | string | yes | Path in Formik state |
externalAuthority | boolean | no | Whether from external authority |
multiple | boolean | no | Enable multiple selections |
filterFunction | func | no | Filter/transform each suggestion |
showLeafsOnly | boolean | no | Show only leaf nodes (hierarchies) |
suggestionAPIHeaders | object | no (Accept header) | HTTP headers for API |
LocalVocabularySelectField
Local vocabulary selector for small vocabularies loaded entirely at once:
import { LocalVocabularySelectField } from "@js/oarepo_vocabularies_ui/form";
<LocalVocabularySelectField
vocabularyName="resource_type"
fieldPath="props.resource_type"
usedOptions={[]}
showLeafsOnly={false}
/>Source: oarepo-vocabularies/LocalVocabularySelectField
Based on: react-invenio-forms.SelectField
Props:
| Prop | Type | Required | Description |
|---|---|---|---|
fieldPath | string | yes | Path in Formik values |
vocabularyName | string | yes | Key to look up options in formConfig.vocabularies |
usedOptions | array | no | Values to keep selectable even if used elsewhere |
multiple | boolean | no | Force multi-select mode |
optimized | boolean | yes | Use optimized select with debounced search |
showLeafsOnly | boolean | no | Show only leaf nodes |
VocabularyPickerField
Flexible picker field for displaying selected vocabulary values with custom selection UI:
import { VocabularyPickerField } from "@js/oarepo_vocabularies_ui/form";
<VocabularyPickerField
fieldPath="props.subjects"
multiple={true}
label="Subjects"
initialValue={[]}
>
<YourVocabularySelector />
</VocabularyPickerField>Source: oarepo-vocabularies/VocabularyPickerField
Based on: Formik context, FieldValueProvider
Props:
| Prop | Type | Required | Description |
|---|---|---|---|
fieldPath | string | yes | Path in Formik values |
label | string | node | no | Field label |
multiple | boolean | no | Enable multiple selections |
required | boolean | no | Mark as required |
initialValue | array | object | no | Starting value |
onChange | func | no | Callback with new value (multi-select only) |
children | node | no | Child selector UI components |
VocabularyMultilingualInputField
Multilingual text input for vocabulary titles/names:
import { VocabularyMultilingualInputField } from "@js/oarepo_vocabularies_ui/form";
<VocabularyMultilingualInputField
fieldPath="title"
label="Title"
required={true}
textFieldLabel="Name"
/>Source: oarepo-vocabularies/VocabularyMultilingualInputField
Based on: react-invenio-forms.ArrayField, LanguageSelectField
Props:
| Prop | Type | Required | Description |
|---|---|---|---|
fieldPath | string | yes | Path to multilingual field |
label | string | no (i18n: “Title”) | Component label |
required | boolean | no | Mark as required |
textFieldLabel | string | no (i18n: “Name”) | Label for inner name field |
displayFirstInputRemoveButton | boolean | no | Show remove on first item |
PropFieldsComponent
Renders custom vocabulary field props as text inputs:
import { PropFieldsComponent } from "@js/oarepo_vocabularies_ui/form";
<PropFieldsComponent vocabularyProps={vocabularyProps} />Source: oarepo-vocabularies/PropFieldsComponent
Based on: react-invenio-forms.TextField
Props:
| Prop | Type | Required | Description |
|---|---|---|---|
vocabularyProps | object | yes | Vocabulary configuration object |
Base Components (from react-invenio-forms)
These components are used by oarepo-ui but imported directly from react-invenio-forms:
ArrayField
Dynamic array wrapper with add button:
import { ArrayField } from "react-invenio-forms";
<ArrayField
fieldPath={fieldPath}
addButtonLabel="Add item"
defaultNewValue={{ name: "" }}
>
{({ arrayHelpers, indexPath }) => (
<div>...</div>
)}
</ArrayField>Source: react-invenio-forms
GroupField
Form field grouping component:
import { GroupField } from "react-invenio-forms";
<GroupField fieldPath="metadata.name">
<TextField fieldPath="metadata.name.given" />
<TextField fieldPath="metadata.name.family" />
</GroupField>Source: react-invenio-forms
AccordionField
Collapsible section container:
import { AccordionField } from "react-invenio-forms";
import { i18next } from "@translations/i18next";
<AccordionField
includesPaths={["metadata.title", "metadata.description"]}
active
label={i18next.t("Basic information")}
>
<TextField fieldPath="metadata.title" />
<TextField fieldPath="metadata.description" />
</AccordionField>Source: react-invenio-forms
Props:
| Prop | Type | Default | Description |
|---|---|---|---|
includesPaths | array | (required) | Field paths triggering accordion expansion |
active | boolean | false | Whether section is expanded by default |
label | string/node | (required) | Section label |
RichInputField
Rich text editor wrapper:
import { RichInputField } from "react-invenio-forms";
<RichInputField
fieldPath="metadata.description"
label="Description"
editor={<OarepoRichEditor />}
/>Source: react-invenio-forms
Note: This component requires explicit field metadata props (label, helpText) unlike oarepo-ui components.