diff --git a/src/lib/forms/RichInputField.js b/src/lib/forms/RichInputField.js index 456b8923..40271f28 100644 --- a/src/lib/forms/RichInputField.js +++ b/src/lib/forms/RichInputField.js @@ -15,7 +15,8 @@ import { Form } from "semantic-ui-react"; export class RichInputField extends Component { renderFormField = (formikBag) => { - const { fieldPath, label, required, className, editor, editorConfig } = this.props; + const { fieldPath, label, required, className, editor, editorConfig, disabled } = + this.props; const value = getIn(formikBag.form.values, fieldPath, ""); const initialValue = getIn(formikBag.form.initialValues, fieldPath, ""); const error = @@ -28,6 +29,7 @@ export class RichInputField extends Component { @@ -74,6 +76,7 @@ RichInputField.propTypes = { label: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), required: PropTypes.bool, editorConfig: PropTypes.object, + disabled: PropTypes.bool, }; RichInputField.defaultProps = { @@ -83,4 +86,5 @@ RichInputField.defaultProps = { label: "", editor: undefined, editorConfig: undefined, + disabled: false, }; diff --git a/src/lib/forms/SelectField.js b/src/lib/forms/SelectField.js index 12575c5f..44d811ac 100644 --- a/src/lib/forms/SelectField.js +++ b/src/lib/forms/SelectField.js @@ -90,15 +90,18 @@ export class SelectField extends Component { }; render() { - const { optimized, fieldPath, ...uiProps } = this.props; + const { optimized, fieldPath, helpText, ...uiProps } = this.props; const FormikField = optimized ? FastField : Field; return ( - + <> + + {helpText && } + ); } } @@ -113,6 +116,7 @@ SelectField.propTypes = { onChange: PropTypes.func, onAddItem: PropTypes.func, multiple: PropTypes.bool, + helpText: PropTypes.string, }; SelectField.defaultProps = { @@ -123,4 +127,5 @@ SelectField.defaultProps = { onChange: undefined, onAddItem: undefined, multiple: false, + helpText: undefined, }; diff --git a/src/lib/forms/widgets/array/Array.js b/src/lib/forms/widgets/array/Array.js index f144e04a..31fe4d9a 100644 --- a/src/lib/forms/widgets/array/Array.js +++ b/src/lib/forms/widgets/array/Array.js @@ -1,10 +1,14 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; - import { FieldLabel } from "../../FieldLabel"; import { ArrayField } from "../../ArrayField"; +import { + fieldCommonProps, + createShowHideComponent, + createDynamicOverridableComponent, +} from "../../../utils"; -export default class Array extends Component { +class _Array extends Component { render() { const { fieldPath, @@ -17,16 +21,21 @@ export default class Array extends Component { addButtonLabel, defaultNewValue, className, + helpText: helpTextProp, + labelIcon: labelIconProp, } = this.props; + const helpText = helpTextProp ?? description; + const labelIcon = labelIconProp ?? icon; + return ( } + label={} addButtonLabel={addButtonLabel} defaultNewValue={defaultNewValue} className={className} @@ -37,22 +46,26 @@ export default class Array extends Component { } } -Array.propTypes = { - fieldPath: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, - icon: PropTypes.string, - required: PropTypes.bool, - disabled: PropTypes.bool, +_Array.propTypes = { children: PropTypes.func.isRequired, addButtonLabel: PropTypes.string.isRequired, defaultNewValue: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, className: PropTypes.string, + /** + * @deprecated Use `labelIcon` instead + */ + icon: PropTypes.string, + /** + * @deprecated Use `helpText` instead + */ + description: PropTypes.string.isRequired, + ...fieldCommonProps, }; -Array.defaultProps = { - icon: undefined, - required: false, - disabled: false, +_Array.defaultProps = { className: "", + icon: undefined, }; + +export const ArrayComponent = createShowHideComponent(_Array); +export const Array = createDynamicOverridableComponent(ArrayComponent); diff --git a/src/lib/forms/widgets/array/index.js b/src/lib/forms/widgets/array/index.js index b1fd8856..d47e11a1 100644 --- a/src/lib/forms/widgets/array/index.js +++ b/src/lib/forms/widgets/array/index.js @@ -1 +1 @@ -export { default as Array } from "./Array"; +export { Array, ArrayComponent } from "./Array"; diff --git a/src/lib/forms/widgets/select/AutocompleteDropdown.js b/src/lib/forms/widgets/select/AutocompleteDropdown.js index 336957f5..ec3ba0c8 100644 --- a/src/lib/forms/widgets/select/AutocompleteDropdown.js +++ b/src/lib/forms/widgets/select/AutocompleteDropdown.js @@ -6,8 +6,13 @@ import _isArray from "lodash/isArray"; import { Field } from "formik"; import { FieldLabel } from "../../FieldLabel"; import { RemoteSelectField } from "../../RemoteSelectField"; +import { + createDynamicOverridableComponent, + createShowHideComponent, + fieldCommonProps, +} from "../../../utils"; -export default class AutocompleteDropdown extends Component { +class _AutocompleteDropdownComponent extends Component { render() { const { description, @@ -20,10 +25,17 @@ export default class AutocompleteDropdown extends Component { multiple, autocompleteFrom, autocompleteFromAcceptHeader, + helpText: helpTextProp, + labelIcon: labelIconProp, + disabled, } = this.props; + + const helpText = helpTextProp ?? description; + const labelIcon = labelIconProp ?? icon; + return ( <> - + {({ form: { values } }) => { return ( @@ -38,6 +50,8 @@ export default class AutocompleteDropdown extends Component { suggestionAPIHeaders={{ Accept: autocompleteFromAcceptHeader, }} + disabled={disabled} + helpText={helpText} serializeSuggestions={(suggestions) => { return _isArray(suggestions) ? suggestions.map((item) => ({ @@ -58,29 +72,39 @@ export default class AutocompleteDropdown extends Component { ); }} - {description && } ); } } -AutocompleteDropdown.propTypes = { - fieldPath: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, +_AutocompleteDropdownComponent.propTypes = { placeholder: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, autocompleteFrom: PropTypes.string.isRequired, autocompleteFromAcceptHeader: PropTypes.string, - icon: PropTypes.string, clearable: PropTypes.bool, multiple: PropTypes.bool, - required: PropTypes.bool, + /** + * @deprecated Use `helpText` instead + */ + description: PropTypes.string, + /** + * @deprecated Use `labelIcon` instead + */ + icon: PropTypes.string, + ...fieldCommonProps, }; -AutocompleteDropdown.defaultProps = { - icon: undefined, +_AutocompleteDropdownComponent.defaultProps = { autocompleteFromAcceptHeader: "application/vnd.inveniordm.v1+json", clearable: false, multiple: false, - required: false, + icon: undefined, + description: undefined, }; + +export const AutocompleteDropdownComponent = createShowHideComponent( + _AutocompleteDropdownComponent +); +export const AutocompleteDropdown = createDynamicOverridableComponent( + AutocompleteDropdownComponent +); diff --git a/src/lib/forms/widgets/select/Dropdown.js b/src/lib/forms/widgets/select/Dropdown.js index 4ce9dc56..119df175 100644 --- a/src/lib/forms/widgets/select/Dropdown.js +++ b/src/lib/forms/widgets/select/Dropdown.js @@ -1,10 +1,14 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; - import { FieldLabel } from "../../FieldLabel"; import { SelectField } from "../../SelectField"; +import { + createDynamicOverridableComponent, + createShowHideComponent, + fieldCommonProps, +} from "../../../utils"; -export default class Dropdown extends Component { +class _DropdownComponent extends Component { serializeOptions = (options) => options?.map((option) => ({ text: option.title_l10n, @@ -15,62 +19,74 @@ export default class Dropdown extends Component { render() { const { description, + helpText: helpTextProp, placeholder, fieldPath, label, icon, + labelIcon: labelIconProp, options, search, multiple, clearable, required, + disabled, } = this.props; + + const helpText = helpTextProp ?? description; + const labelIcon = labelIconProp ?? icon; + return ( - <> - } - options={this.serializeOptions(options)} - search={search} - aria-label={label} - multiple={multiple} - placeholder={{ - role: "option", - content: placeholder, - }} - clearable={clearable} - required={required} - optimized - defaultValue={multiple ? [] : ""} - /> - {description && } - + } + options={this.serializeOptions(options)} + search={search} + aria-label={label} + multiple={multiple} + disabled={disabled} + placeholder={{ + role: "option", + content: placeholder, + }} + clearable={clearable} + required={required} + optimized + defaultValue={multiple ? [] : ""} + helpText={helpText} + /> ); } } -Dropdown.propTypes = { - fieldPath: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - placeholder: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, +_DropdownComponent.propTypes = { options: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string.isRequired, title_l10n: PropTypes.string.isRequired, }) ).isRequired, - icon: PropTypes.string, search: PropTypes.bool, multiple: PropTypes.bool, clearable: PropTypes.bool, - required: PropTypes.bool, + /** + * @deprecated Use `helpText` instead + */ + description: PropTypes.string, + /** + * @deprecated Use `labelIcon` instead + */ + icon: PropTypes.string, + ...fieldCommonProps, }; -Dropdown.defaultProps = { +_DropdownComponent.defaultProps = { icon: undefined, search: false, multiple: false, clearable: true, - required: false, + description: undefined, }; + +export const DropdownComponent = createShowHideComponent(_DropdownComponent); +export const Dropdown = createDynamicOverridableComponent(DropdownComponent); diff --git a/src/lib/forms/widgets/select/index.js b/src/lib/forms/widgets/select/index.js index 6081f4b9..ee9c34db 100644 --- a/src/lib/forms/widgets/select/index.js +++ b/src/lib/forms/widgets/select/index.js @@ -1,2 +1,5 @@ -export { default as AutocompleteDropdown } from "./AutocompleteDropdown"; -export { default as Dropdown } from "./Dropdown"; +export { + AutocompleteDropdown, + AutocompleteDropdownComponent, +} from "./AutocompleteDropdown"; +export { Dropdown, DropdownComponent } from "./Dropdown"; diff --git a/src/lib/forms/widgets/text/BooleanCheckbox.js b/src/lib/forms/widgets/text/BooleanCheckbox.js index 533f828d..468754a9 100644 --- a/src/lib/forms/widgets/text/BooleanCheckbox.js +++ b/src/lib/forms/widgets/text/BooleanCheckbox.js @@ -12,8 +12,13 @@ import { FieldLabel } from "../../FieldLabel"; import { RadioField } from "../../RadioField"; import { useField } from "formik"; +import { + createDynamicOverridableComponent, + createShowHideComponent, + fieldCommonProps, +} from "../../../utils"; -export default function BooleanCheckbox({ +function _BooleanCheckboxComponent({ description, icon, falseLabel, @@ -21,14 +26,19 @@ export default function BooleanCheckbox({ label, trueLabel, required, + helpText: helpTextProp, + labelIcon: labelIconProp, }) { + const helpText = helpTextProp ?? description; + const labelIcon = labelIconProp ?? icon; + // eslint-disable-next-line no-unused-vars const [_, meta] = useField(fieldPath); return ( <> - + )} - {description && } + {helpText && } ); } -BooleanCheckbox.propTypes = { - fieldPath: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, +_BooleanCheckboxComponent.propTypes = { trueLabel: PropTypes.string.isRequired, falseLabel: PropTypes.string.isRequired, + /** + * @deprecated Use `helpText` instead + */ description: PropTypes.string.isRequired, + /** + * @deprecated Use `labelIcon` instead + */ icon: PropTypes.string, - required: PropTypes.bool, + ...fieldCommonProps, }; -BooleanCheckbox.defaultProps = { +_BooleanCheckboxComponent.defaultProps = { icon: undefined, required: false, }; + +export const BooleanCheckboxComponent = createShowHideComponent( + _BooleanCheckboxComponent +); +export const BooleanCheckbox = createDynamicOverridableComponent( + BooleanCheckboxComponent +); diff --git a/src/lib/forms/widgets/text/Input.js b/src/lib/forms/widgets/text/Input.js index 420af472..0ae90521 100644 --- a/src/lib/forms/widgets/text/Input.js +++ b/src/lib/forms/widgets/text/Input.js @@ -1,10 +1,14 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; - import { FieldLabel } from "../../FieldLabel"; import { TextField } from "../../TextField"; +import { + createShowHideComponent, + createDynamicOverridableComponent, + fieldCommonProps, +} from "../../../utils/"; -export default class Input extends Component { +class _InputComponent extends Component { render() { const { fieldPath, @@ -15,16 +19,21 @@ export default class Input extends Component { description, disabled, type, + helpText: helpTextProp, + labelIcon: labelIconProp, } = this.props; + const helpText = helpTextProp ?? description; + const labelIcon = labelIconProp ?? icon; + return ( } + label={} placeholder={placeholder} type={type} /> @@ -32,20 +41,23 @@ export default class Input extends Component { } } -Input.propTypes = { - fieldPath: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - placeholder: PropTypes.string.isRequired, +_InputComponent.propTypes = { + /** + * @deprecated Use `helpText` instead + */ description: PropTypes.string.isRequired, + /** + * @deprecated Use `labelIcon` instead + */ icon: PropTypes.string, - required: PropTypes.bool, - disabled: PropTypes.bool, type: PropTypes.string, + ...fieldCommonProps, }; -Input.defaultProps = { +_InputComponent.defaultProps = { icon: undefined, - required: false, - disabled: false, type: "input", }; + +export const InputComponent = createShowHideComponent(_InputComponent); +export const Input = createDynamicOverridableComponent(InputComponent); diff --git a/src/lib/forms/widgets/text/MultiInput.js b/src/lib/forms/widgets/text/MultiInput.js index 4a71a082..d83cbd3d 100644 --- a/src/lib/forms/widgets/text/MultiInput.js +++ b/src/lib/forms/widgets/text/MultiInput.js @@ -1,11 +1,15 @@ import React, { useState } from "react"; import PropTypes from "prop-types"; import { useFormikContext, getIn } from "formik"; - import { FieldLabel } from "../../FieldLabel"; import { SelectField } from "../../SelectField"; +import { + createDynamicOverridableComponent, + createShowHideComponent, + fieldCommonProps, +} from "../../../utils"; -export default function MultiInput({ +function _MultiInputComponent({ additionLabel, description, placeholder, @@ -13,6 +17,9 @@ export default function MultiInput({ label, icon, required, + disabled, + helpText: helpTextProp, + labelIcon: labelIconProp, }) { const [options, setOptions] = useState([]); const { values } = useFormikContext(); @@ -23,14 +30,18 @@ export default function MultiInput({ value: item, })); + const helpText = helpTextProp ?? description; + const labelIcon = labelIconProp ?? icon; + return ( <> } + label={} options={serializeValues(getIn(values, fieldPath, []))} placeholder={placeholder} required={required} + disabled={disabled} search multiple clearable @@ -47,23 +58,28 @@ export default function MultiInput({ setOptions([{ text: data.value, value: data.value }, ...options]); }} /> - {description && } + {helpText && } ); } -MultiInput.propTypes = { - fieldPath: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - placeholder: PropTypes.string.isRequired, +_MultiInputComponent.propTypes = { + /** + * @deprecated Use `helpText` instead + */ description: PropTypes.string.isRequired, additionLabel: PropTypes.string, + /** + * @deprecated Use `labelIcon` instead + */ icon: PropTypes.string, - required: PropTypes.bool, + ...fieldCommonProps, }; -MultiInput.defaultProps = { +_MultiInputComponent.defaultProps = { additionLabel: undefined, icon: undefined, - required: false, }; + +export const MultiInputComponent = createShowHideComponent(_MultiInputComponent); +export const MultiInput = createDynamicOverridableComponent(MultiInputComponent); diff --git a/src/lib/forms/widgets/text/NumberInput.js b/src/lib/forms/widgets/text/NumberInput.js index b76913b8..b07d5c75 100644 --- a/src/lib/forms/widgets/text/NumberInput.js +++ b/src/lib/forms/widgets/text/NumberInput.js @@ -1,5 +1,10 @@ import React from "react"; -import Input from "./Input"; +import { + createDynamicOverridableComponent, + createShowHideComponent, +} from "../../../utils"; +import { InputComponent } from "./Input"; -const NumberInput = (props) => ; -export default NumberInput; +const _NumberInputComponent = (props) => ; +export const NumberInputComponent = createShowHideComponent(_NumberInputComponent); +export const NumberInput = createDynamicOverridableComponent(NumberInputComponent); diff --git a/src/lib/forms/widgets/text/RichInput.js b/src/lib/forms/widgets/text/RichInput.js index 9aa6b0b4..9281b635 100644 --- a/src/lib/forms/widgets/text/RichInput.js +++ b/src/lib/forms/widgets/text/RichInput.js @@ -1,38 +1,63 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; - import { FieldLabel } from "../../FieldLabel"; import { RichInputField } from "../../RichInputField"; +import { + createDynamicOverridableComponent, + createShowHideComponent, + fieldCommonProps, +} from "../../../utils"; -export default class RichInput extends Component { +class _RichInputComponent extends Component { render() { - const { fieldPath, required, label, icon, description, editorConfig } = this.props; + const { + fieldPath, + required, + label, + icon, + description, + editorConfig, + disabled, + helpText: helpTextProp, + labelIcon: labelIconProp, + } = this.props; + + const helpText = helpTextProp ?? description; + const labelIcon = labelIconProp ?? icon; + return ( <> } + label={} /> - {description && } + {helpText && } ); } } -RichInput.propTypes = { - fieldPath: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, +_RichInputComponent.propTypes = { editorConfig: PropTypes.object, + /** + * @deprecated Use `labelIcon` instead + */ icon: PropTypes.string, - required: PropTypes.bool, + /** + * @deprecated Use `helpText` instead + */ + description: PropTypes.string.isRequired, + ...fieldCommonProps, }; -RichInput.defaultProps = { +_RichInputComponent.defaultProps = { icon: undefined, editorConfig: {}, - required: false, }; + +export const RichInputComponent = createShowHideComponent(_RichInputComponent); +export const RichInput = createDynamicOverridableComponent(RichInputComponent); diff --git a/src/lib/forms/widgets/text/TextArea.js b/src/lib/forms/widgets/text/TextArea.js index 5d0cb855..f8db73fe 100644 --- a/src/lib/forms/widgets/text/TextArea.js +++ b/src/lib/forms/widgets/text/TextArea.js @@ -1,12 +1,29 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; - import { FieldLabel } from "../../FieldLabel"; import { TextAreaField } from "../../TextAreaField"; +import { + createShowHideComponent, + createDynamicOverridableComponent, + fieldCommonProps, +} from "../../../utils"; -export default class TextArea extends Component { +class _TextAreaComponent extends Component { render() { - const { fieldPath, required, label, icon, description, rows } = this.props; + const { + fieldPath, + required, + label, + icon, + description, + rows, + disabled, + helpText: helpTextProp, + labelIcon: labelIconProp, + } = this.props; + + const helpText = helpTextProp ?? description; + const labelIcon = labelIconProp ?? icon; return ( <> @@ -14,26 +31,33 @@ export default class TextArea extends Component { key={fieldPath} fieldPath={fieldPath} required={required} - label={} + disabled={disabled} rows={rows} + label={} /> - {description && } + {helpText && } ); } } -TextArea.propTypes = { - fieldPath: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, - icon: PropTypes.string, - required: PropTypes.bool, +_TextAreaComponent.propTypes = { rows: PropTypes.number, + /** + * @deprecated Use `labelIcon` instead + */ + icon: PropTypes.string, + /** + * @deprecated Use `helpText` instead + */ + description: PropTypes.string.isRequired, + ...fieldCommonProps, }; -TextArea.defaultProps = { +_TextAreaComponent.defaultProps = { icon: undefined, - required: false, rows: 3, }; + +export const TextAreaComponent = createShowHideComponent(_TextAreaComponent); +export const TextArea = createDynamicOverridableComponent(TextAreaComponent); diff --git a/src/lib/forms/widgets/text/index.js b/src/lib/forms/widgets/text/index.js index b6e59f60..6c1a1c0e 100644 --- a/src/lib/forms/widgets/text/index.js +++ b/src/lib/forms/widgets/text/index.js @@ -1,6 +1,6 @@ -export { default as RichInput } from "./RichInput"; -export { default as TextArea } from "./TextArea"; -export { default as Input } from "./Input"; -export { default as MultiInput } from "./MultiInput"; -export { default as NumberInput } from "./NumberInput"; -export { default as BooleanCheckbox } from "./BooleanCheckbox"; +export { RichInput, RichInputComponent } from "./RichInput"; +export { TextArea, TextAreaComponent } from "./TextArea"; +export { Input, InputComponent } from "./Input"; +export { MultiInput, MultiInputComponent } from "./MultiInput"; +export { NumberInput, NumberInputComponent } from "./NumberInput"; +export { BooleanCheckbox, BooleanCheckboxComponent } from "./BooleanCheckbox"; diff --git a/src/lib/utils/fieldComponents.js b/src/lib/utils/fieldComponents.js new file mode 100644 index 00000000..bb5bf7ec --- /dev/null +++ b/src/lib/utils/fieldComponents.js @@ -0,0 +1,88 @@ +// This file is part of React-Invenio-Forms +// Copyright (C) 2022-2025 CERN. +// Copyright (C) 2022 Northwestern University. +// +// React-Invenio-Forms is free software; you can redistribute it and/or modify it +// under the terms of the MIT License; see LICENSE file for more details. + +import PropTypes from "prop-types"; +import React from "react"; +import Overridable from "react-overridable"; + +// Props used for fields that are mandatory for all records +export const mandatoryFieldCommonProps = { + fieldPath: PropTypes.string.isRequired, + label: PropTypes.string, + labelIcon: PropTypes.string, + helpText: PropTypes.string, + placeholder: PropTypes.string, +}; + +// Also includes props that allow not including a field in the form, which are not applicable +// to mandatory fields. +export const fieldCommonProps = { + ...mandatoryFieldCommonProps, + hidden: PropTypes.bool, + disabled: PropTypes.bool, + required: PropTypes.bool, +}; + +/** + * Creates a component that de-renders when the `hidden` prop is `true`. + * All props passed to the `ShowHideComponent` are forwarded to the child component except the `hidden` prop. + * + * @param Component - The child component + * @param {string=} id - An optional OverridableID for debugging purposes + */ +export const createShowHideComponent = (Component, id) => { + const ShowHideComponent = ({ hidden, ...props }) => { + if (props.disabled && props.required) { + throw new Error(`Cannot make field component ${id} both required and disabled`); + } + if (hidden) return null; + return ; + }; + + ShowHideComponent.displayName = `ShowHide(${ + Component.displayName || Component.name + })`; + ShowHideComponent.propTypes = { ...Component.propTypes }; + ShowHideComponent.defaultProps = { ...Component.defaultProps }; + return ShowHideComponent; +}; + +/** + * Creates an overridable component with show/hide functionality based on the `hidden` prop. + * All high-level fields in the deposit form are exported through this function, and this + * is the only version of the component that should be exported. + * + * @param {string} id - The Overridable ID to use + * @param Child - The unexported child component + */ +export const createCommonDepositFieldComponent = (id, Child) => { + const Component = createShowHideComponent(Child); + Component.propTypes = Child.propTypes; + return Overridable.component(id, Component); +}; + +/** + * Create a component whos Overridable ID is defined via a prop at runtime rather than pre-assigned. + * This is necessary for custom fields, where Python will inject the Overridable ID from the user's + * configuration, allowing features like `parametrize` to be applied also to custom fields. + */ +export const createDynamicOverridableComponent = (Widget) => { + const Component = ({ id, ...props }) => { + if (id === undefined) return ; + + return ( + + + + ); + }; + + Component.propTypes = { ...Widget.propTypes, id: PropTypes.string }; + Component.defaultProps = { ...Widget.defaultProps, id: undefined }; + Component.displayName = `DynamicOverridable(${Widget.displayName || Widget.name})`; + return Component; +}; diff --git a/src/lib/utils/index.js b/src/lib/utils/index.js index 9f213050..07dc3293 100644 --- a/src/lib/utils/index.js +++ b/src/lib/utils/index.js @@ -1,2 +1,9 @@ export { humanReadableBytes } from "./humanReadableBytes"; export { dropdownOptionsGenerator } from "./dropdownOptionsGenerator"; +export { + createCommonDepositFieldComponent, + createDynamicOverridableComponent, + createShowHideComponent, + fieldCommonProps, + mandatoryFieldCommonProps, +} from "./fieldComponents";