Skip to content

Commit ce2190b

Browse files
committed
overridable: rearrange guide page
* Rearranged the content of `override_components.md` according to suggestions from @fenekku
1 parent b083cbd commit ce2190b

File tree

1 file changed

+76
-90
lines changed

1 file changed

+76
-90
lines changed

docs/operate/customize/look-and-feel/override_components.md

Lines changed: 76 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
*Introduced in InvenioRDM v11*
44

5-
This documentation is targeted to developers who want to customize specific UI React components in an instance.
5+
This documentation is targeted at developers who want to customize specific UI React components in an instance.
66
For this guide, we assume that you are familiar with React and JavaScript.
77

8-
## Override React components
8+
## About overriding
99

1010
!!! warning "Experimental feature"
1111

@@ -18,44 +18,34 @@ For this guide, we assume that you are familiar with React and JavaScript.
1818
The UI of InvenioRDM is composed of classic HTML web pages for mostly static content, and React web apps for very dynamic content to enhance the user experience.
1919
While a [dedicated guide](./templates.md) describes how to override HTML web pages (Jinja templates), this guide focus on how to override React components.
2020

21-
InvenioRDM uses the React library [`react-overridable`](https://github.com/indico/react-overridable). The library provides a mechanism to mark React components as "overridable" by ID.
21+
InvenioRDM uses the React library [`react-overridable`](https://github.com/indico/react-overridable).
22+
The library provides a mechanism to mark React components as "overridable" by ID, which is implemented for many components across the InvenioRDM codebase.
2223
Developers can define a mapping which is then applied when each React component is rendered.
23-
The override can be specified in one of three ways:
2424

25-
- completely replacing a component with a custom one
26-
- a static override of the props passed to the component
27-
- a 'dynamic' override of the props based on the form's state
28-
29-
As example for this guide, you will learn how to override the UI React component **in the upload form that marks a record as "Metadata only"**. More specifically, you will replace the "Metadata-only record" checkbox with a toggle, a "switch-like" component.
25+
## 1. Find the component to override
3026

31-
![Metadata-only record checkbox](./imgs/metadata_only_checkbox.png)
32-
33-
## Guided example
34-
35-
### 1. Identify which component to override
36-
37-
At the moment, the easiest way to understand how to identify if the component that you want to override is a classic HTML component or a React component is to use the Developer Tools in your browser (e.g. [Chrome](https://developer.chrome.com/docs/devtools/) or [Firefox DevTools](https://firefox-source-docs.mozilla.org/devtools-user/)). You can inspect the code and take advantage of some useful [React browser extensions](https://beta.reactjs.org/learn/react-developer-tools) to select and inspect elements:
27+
At the moment, the easiest way to identify if the component that you want to override is a classic HTML component or a React component is to use the Developer Tools in your browser (e.g. [Chrome](https://developer.chrome.com/docs/devtools/) or [Firefox DevTools](https://firefox-source-docs.mozilla.org/devtools-user/)). You can inspect the code and take advantage of the [React Developer Tools](https://react.dev/learn/react-developer-tools) browser extension to select and inspect elements:
3828

3929
![React browser extension example](./imgs/react_browser_extension_example.png)
4030

41-
You can then find the component in the InvenioRDM modules source code, searching it in your local development environment or using the search feature in GitHub in the [inveniosoftware organization](https://github.com/search?q=org%3Ainveniosoftware+FileUploaderToolbar&type=code).
42-
43-
You can always [ask for help](../../../install/troubleshoot.md#getting-help)!
31+
If the component shows up in the React tree, it is a React component and can be overriden using the methods described on this page.
32+
Otherwise, it is an HTML component that can be [overriden using Jinja templates](./templates.md).
4433

45-
### 2. Find the React Overridable ID
46-
47-
The easiest way to to find the ID of an overridable component is to use `react-overridable`'s built-in developer tool.
34+
Next, you can find the ID of an overridable component using `react-overridable`'s built-in developer tool.
4835
Simply open a browser console on your local instance and call the global function `reactOverridableEnableDevMode()`.
4936
All overridable components will display a small red overlay tag showing their ID.
5037
You can click a tag to copy its ID to your clipboard.
5138

5239
![Metadata-only checkbox overridable ID in an overlay](./imgs/metadata_id_overlay.png)
5340

54-
The React component's overridable ID for the '`Metadata-only record`' checkbox component is `InvenioRdmRecords.DepositForm.FileUploaderToolbar.MetadataOnlyToggle`. It can be found in the [`invenio-rdm-records`](https://github.com/inveniosoftware/invenio-rdm-records/blob/dd72962b713f07b81699f7d5c9a8a673d585466a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/FileUploader/FileUploaderToolbar.js#L56) module.
41+
You can search the ID in the [`inveniosoftware` organisation on GitHub](https://github.com/inveniosoftware/) to find the component and its props, which
42+
can be helpful when overriding.
43+
44+
If you're struggling, you can always [ask for help](../../../install/troubleshoot.md#getting-help)!
5545

56-
### 3. Find or create the mapping file
46+
## 2. Find or create the mapping file
5747

58-
In new InvenioRDM v11 or above installations, a near-empty file named `mapping.js` is available at the following path in your `assets` folder:
48+
In new InvenioRDM installations at v11 or above, a near-empty file named `mapping.js` is available at the following path in your `assets` folder:
5949

6050
```terminal
6151
├── assets
@@ -71,75 +61,24 @@ For existing installations, you will have to create it. It is a very simple file
7161
export const overriddenComponents = {};
7262
```
7363

74-
The `const overriddenComponents` is the map that will contain all your future overridden components.
75-
76-
### 4. Create a new component creation
77-
78-
Let's create a new React component, very similar to the default `FileUploaderToolbar`, changing the UI component that will render. In the same file `mapping.js`, add the following code above the `const overriddenComponents`:
64+
The `const overriddenComponents` is the map that will contain all your future overrides.
7965

80-
```javascript
81-
import React from "react";
82-
import { Checkbox } from "semantic-ui-react";
83-
import { useFormikContext } from "formik";
84-
import PropTypes from "prop-types";
85-
86-
const MetadataToggle = (props) => {
87-
const { filesEnabled } = props;
88-
const { setFieldValue } = useFormikContext();
89-
90-
const handleOnChangeMetadataOnly = () => {
91-
setFieldValue("files.enabled", !filesEnabled);
92-
setFieldValue("access.files", "public");
93-
};
94-
95-
return (
96-
<Checkbox
97-
toggle
98-
label="Metadata-only record"
99-
onChange={handleOnChangeMetadataOnly}
100-
/>
101-
);
102-
};
66+
## 3. Override the component
10367

104-
export default MetadataToggle;
105-
106-
MetadataToggle.propTypes = {
107-
filesEnabled: PropTypes.bool.isRequired,
108-
};
109-
```
110-
111-
Now, change the map by adding your new component:
112-
113-
```javascript
114-
...
115-
116-
export const overriddenComponents = {
117-
"InvenioRdmRecords.DepositForm.FileUploaderToolbar.MetadataOnlyToggle": MetadataToggle,
118-
};
119-
```
120-
121-
Lastly, rebuild your assets and run the instance:
122-
123-
```terminal
124-
cd my-site
125-
invenio-cli assets build
126-
invenio-cli run
127-
```
68+
The override can be specified in one of three ways, depending on your use case and the amount of control you require:
12869

129-
When navigating to the upload form, you should now see your new React component instead of the default:
130-
131-
!["`Metadata-only record`" toggle](./imgs/metadata_only_toggle.png)
132-
133-
## Overriding props only
134-
135-
In many cases, you simply want to make a small modification to a component by changing one of its props instead of recreating the component from scratch by yourself.
136-
This can either be done by specifying the desired prop overrides statically, or by expressing them as a function of the form state.
70+
- a static override of the props passed to the component
71+
- a 'dynamic' override of the props based on the form's state
72+
- completely replacing a component with a custom one
13773

138-
### Static
74+
### a. Statically override a component's props
13975

14076
You can use the `parametrize` function built into `react-overridable`, into which you need to pass the component you wish to override and an object containing your props.
14177
These props will be 'merged' with the existing props, with yours taking precedence over existing ones of the same name.
14278

79+
In this case, the props are defined once in your `mapping.js` file and are not updated during the runtime of the application.
80+
You are also unable to access any React/Formik context while defining the props.
81+
14382
```javascript
14483
import { parametrize } from "react-overridable"
14584
import { TitlesField } from "@js/invenio_rdm_records"
@@ -154,7 +93,7 @@ export const overriddenComponents = {
15493
}
15594
```
15695

157-
### Dynamic
96+
### b. Dynamically override a component's props
15897

15998
To implement more complex functionality in the deposit form, you can override the props of components by using a custom function.
16099
This allows you to express a range of behaviours:
@@ -190,7 +129,54 @@ The callback function is currently passed an object as its single argument, cont
190129
- `formValues`: the raw values of the entire deposit form as given by Formik. The majority of field values are under the `metadata` key.
191130
- `existingProps`: the props passed to the element before your override.
192131

193-
### Deposit form field props
132+
### c. Fully replace a component
133+
134+
To fully replace a component with your custom one, first create the component definition within your instance's source code.
135+
For example:
136+
137+
```jsx
138+
import React from "react";
139+
import { Checkbox } from "semantic-ui-react";
140+
import { useFormikContext } from "formik";
141+
import PropTypes from "prop-types";
142+
143+
const MetadataToggle = (props) => {
144+
const { filesEnabled } = props;
145+
const { setFieldValue } = useFormikContext();
146+
147+
const handleOnChangeMetadataOnly = () => {
148+
setFieldValue("files.enabled", !filesEnabled);
149+
setFieldValue("access.files", "public");
150+
};
151+
152+
return (
153+
<Checkbox
154+
toggle
155+
label="Metadata-only record"
156+
onChange={handleOnChangeMetadataOnly}
157+
/>
158+
);
159+
};
160+
161+
export default MetadataToggle;
162+
163+
MetadataToggle.propTypes = {
164+
filesEnabled: PropTypes.bool.isRequired,
165+
};
166+
```
167+
168+
Now, change the map by adding your new component:
169+
170+
```javascript
171+
...
172+
173+
export const overriddenComponents = {
174+
"InvenioRdmRecords.DepositForm.FileUploaderToolbar.MetadataOnlyToggle": MetadataToggle,
175+
};
176+
```
177+
178+
179+
## Common field props in the deposit form
194180

195181
The built-in fields in the deposit form (e.g. title, description, etc.) have a number of common props to make customizing basic functionality easier.
196182

@@ -202,7 +188,7 @@ The following props may be overriden on all built-in fields:
202188
- `placeholder`: same as the [HTML attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/placeholder)
203189

204190
Additionally, the following props may be overriden on fields that are not mandatory.
205-
At the moment, this is all fields except the Resource Type, Title, Publication Date, and Creatibutors.
191+
At the moment, this is all fields except Resource Type, Title, Publication Date, and Creatibutors.
206192

207193
- `hidden`: if `true`, the field is not rendered at all
208194
- If a field already had a value before being hidden, this will still be included in the model and will be sent to the server when the form is submitted.
@@ -214,7 +200,7 @@ At the moment, this is all fields except the Resource Type, Title, Publication D
214200
Many fields have their own props in addition to these.
215201
Please [view the source code](https://github.com/inveniosoftware/invenio-rdm-records/tree/master/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields) for more details.
216202

217-
## Other examples
203+
## Examples
218204

219205
### Showing/hiding
220206

0 commit comments

Comments
 (0)