As you might know, UI Core version 4 has recently been released. We recommend you check out our changelog for the full list of changes. There are also live demos and API docs at https://ui-core.dhis2.nu.

To help you upgrade to ui-core 4 we’ll briefly go through the most important changes that require your attention:

  • Form controls look and feel
  • Form controls and Field components
  • Callback style
  • Select component removal
  • SingleSelect and MultiSelect components introduced
  • TextArea and TextAreaField introduced
  • React version requirement changed
  • Removal of nested component (Component.Component) pattern
  • And more…

Why have the input fields changed?

There are three main reasons for the breaking change in the input fields:

  1. The previous inputs were not recognizable enough as inputs for all users

  2. There were no good reasons to maintain multiple input styles

  3. The filled and outlined inputs sometimes interchanged the use of labels and/or placeholder text. This needed to be simplified to define clearly the roles of the label and placeholder.

The previous filled and outlined inputs were inherited from our use of Material UI. When building our own UI library we have been able to create an input component that is right for DHIS2 applications. The new input component is:

  • Recognizable: it looks and behaves like input fields most users are familiar with

  • Understandable: there are no animations or moving parts to distract from its core use

  • Using obvious label and placeholder texts: a label is always above, a placeholder text is always within. Using one does not affect the other.

If you haven’t already, make sure to remove the filled prop from your ui-core Inputs and InputFields, as it no longer does anything.

*Field components

You’ll notice we’ve mentioned the Input and InputField above. All of our form components now have a <componentname>Field equivalent. The Field variants add props for commonly used patterns like a label, validationText, helpText and more. See our API docs for the complete list.

New callback style

The callback style for ui-core components has changed. Previously any callbacks passed to our components would be called with the synthetic event. We’re now calling all callbacks with an object with relevant data first, and the synthetic event second. To clarify, this is for example how the onChange prop on our Input component now works:

<Input
    name="inputname"
    onChange={({ data, event }) => {
        const { value, name } = data

        // the same as event.target.value
        console.log(value)
        // will log "inputname", see the "name" prop above
        console.log(name)
    }}
    // other props omitted for clarity
/>

We’ve done this because ui-core 4 introduced non-native components, and this allows us to pass any custom data besides the event. To keep things consistent, we’ve adopted this pattern for all our components. See our changelog for the exact properties passed in the first argument.

Select deprecation

Speaking of non-native components, the Select component has been deprecated In favor of the new SingleSelect and MultiSelect components. They’re not backed by the native select element, and thus allow us to create a select component that is more in line with modern UI and UX expectations. As a small example, this is how the new SingleSelect and MultiSelect can be used:

import React from 'react'
import {
    SingleSelect,
    SingleSelectOption,
    MultiSelect,
    MultiSelectOption,
} from '@dhis2/ui-core'

const singleSelected = { value: '1', label: 'one' }
const multipleSelected = [
    { value: '1', label: 'one' },
    { value: '2', label: 'two' },
]

const Example = () => (
    <div>
        <SingleSelect
            selected={singleSelected}
            onChange={({ selected }) => {
                alert(
                    `Selected changed to: ${JSON.stringify(selected, null, 2)}`
                )
            }}
        >
            <SingleSelectOption value="1" label="one" />
            <SingleSelectOption value="2" label="two" />
            <SingleSelectOption value="3" label="three" />
        </SingleSelect>
        <MultiSelect
            selected={multipleSelected}
            onChange={({ selected }) => {
                alert(
                    `Selected changed to: ${JSON.stringify(selected, null, 2)}`
                )
            }}
        >
            <MultiSelectOption value="1" label="one" />
            <MultiSelectOption value="2" label="two" />
            <MultiSelectOption value="3" label="three" />
        </MultiSelect>
    </div>
)

New components

We’ve added several other new components, most notably:

  • Textarea and TextareaField
  • FileInput and FileInputField.

React version

There has been a slight bump in the required react version, ui-core now requires at least react 16.8 and react-dom 16.8.

Smaller changes

  • The Modal now always renders (instead of accepting an open prop). Make sure to not render it if you don’t want it to be displayed.

  • Besides the user-facing changes listed above, we’ve added a lot of integration tests for our components and are in the process of adding more.

  • The TabBar no longer has to be nested in a ScrollBar, instead the TabBar now has a scrollable prop.

  • Modal.Actions, Modal.Content and Modal.Title have been removed. Instead you can use ModalActions, ModalContent and ModalTitle.

  • className props are allowed on all our components, but note that we do not guarantee that styling component internals won’t break, so use with care.

  • Our theme now also exposes spacers, elevations and layer constants.

We hope the above is useful in your upgrade to version 4 of ui-core. Let us know if you encounter anything, and feel free to open an issue or PR!