Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

refactor(toggle-group): split into composable components and generalise #388

Merged
merged 10 commits into from
Aug 27, 2019

Conversation

HendrikThePendric
Copy link
Contributor

Based on the excellent #381 (comment) @varl placed on my previous PR which had been merged already, I've come up with a much more composable solution in this PR.

Some notes:

  1. I quickly realised that this way of implementing it is much more flexible, and would allow us to reuse this component for grouping Checkboxes and Switches too. As such I've renamed everything that was radio to toggle, which is the most descriptive word I could come up with to describe radio/checkbox/switch inputs.
  2. We really need to have a label of some kind to put above the set of 'toggles'. I found it hard to come up with a suitable name, and also wasn't sure if this would be something we would want to expose individually. So as an alternative, this is now exposed as ToggleGroup.Label. This is the best I could come up with, but still isn't perfect, because the ToggleGroup.Label is actually above the ToggleGroup and not inside of it...

Looking forward to finding out what you think of this second attempt.

@varl
Copy link
Contributor

varl commented Aug 23, 2019

Much better. 👍

Could this be so general as to accommodate other field components? In that case we could rename the ToggleGroup to e.g. FieldSet and implement it as a fieldset component under the hood.

2. We really need to have a label of some kind to put above the set of 'toggles'. I found it hard to come up with a suitable name, and also wasn't sure if this would be something we would want to expose individually. So as an alternative, this is now exposed as ToggleGroup.Label. This is the best I could come up with, but still isn't perfect, because the ToggleGroup.Label is actually above the ToggleGroup and not inside of it...

This sounds like a HTML <fieldset>, + a HTML <legend>.

We can provide our own styled component pair: FieldSet and Legend. They would be exposed individually and could technically be used with other fields as well. E.g.

<FieldSet stacked>
  <Legend>Toggle fields</Legend>
  <Radio />
  <Switch />
</FieldSet>
<FieldSet>
  <Legend>Input fields</Legend>
  <InputField />
  <SelectField />
</FieldSet>

fieldset elements can be nested as well: https://codepen.io/varl/pen/pozRWxb

@varl
Copy link
Contributor

varl commented Aug 23, 2019

Since removing an exposed component is a BREAKING CHANGE we should consider if we should rename InputField to Input and SelectField to Select to be more consistent with the other form elements e.g. Switch, Radio, Checkbox, that do not have the -Field suffix.

@Mohammer5
Copy link
Contributor

Since removing an exposed component is a BREAKING CHANGE we should consider if we should rename InputField to Input and SelectField to Select to be more consistent with the other form elements e.g. Switch, Radio, Checkbox, that do not have the -Field suffix.

A very welcomed change on my side, these name annoyed me ever since I encountered them the first time


This sounds like a HTML <fieldset>, + a HTML <legend>.

I wouldn't mind using these elements, we just have to be aware, that we'll need an extra wrapper for the input elements if we wanted them to be flexed:

Note: as of this writing, there are bugs in Microsoft Edge and Google Chrome which prevent flexbox and grid layouts from being used inside a <fieldset>. This GitHub issue provides bug tracking links.

@varl varl changed the base branch from master to next August 23, 2019 06:52
@varl
Copy link
Contributor

varl commented Aug 23, 2019

This sounds like a HTML <fieldset>, + a HTML <legend>.

I wouldn't mind using these elements, we just have to be aware, that we'll need an extra wrapper for the input elements if we wanted them to be flexed:

Note: as of this writing, there are bugs in Microsoft Edge and Google Chrome which prevent flexbox and grid layouts from being used inside a <fieldset>. This GitHub issue provides bug tracking links.

Nice catch, we do need to consider that. 🤔

@varl
Copy link
Contributor

varl commented Aug 23, 2019

A very welcomed change on my side, these name annoyed me ever since I encountered them the first time

#389

@HendrikThePendric
Copy link
Contributor Author

This PR can now be reviewed again.

One note:
Because we are now rendering the <legend> from the FieldSet, this component now also needs to know about statuses (error, warning, valid) + required.... Previously, when it was ToggleGroup it was nicely separated. So this is a minor drawback, but overall I think this implementation is good....

@varl
Copy link
Contributor

varl commented Aug 26, 2019

@cooper-joe could you have a look at the statuses of the FieldSet?

@varl varl requested a review from cooper-joe August 26, 2019 17:54
stories/InputField.stories.js Outdated Show resolved Hide resolved
{Children.map(children, child =>
cloneElement(child, {
className: cx(child.props.className, 'fieldset-input'),
valid,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always forwarding the statuses is not good in my opinion.
A fieldset can also be used to group logical inputs that don't have the same name attribute, like this:

<fieldset>
	<legend>Personal details</legend>
	<label for="first-name">First name</label>
	<input name="first-name" id="first-name" type="text">
	<label for="family-name">Family name</label>
	<input name="family-name" id="family-name" type="text">
	<label for="email">Email</label>
	<input name="email" id="email" type="text">
</fieldset>

(source: http://usability.com.au/2013/04/accessible-forms-1-labels-and-identification/)


I'd propose a forwardStatus prop that defaults to false (or no default, which is falsy)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good that you bring this up, because I was having second thoughts about this too. Upon reflection, I actually don't think we should forward these props at all. By forwarding these props we could be creating unexpected behaviour:

  • suppose the error prop of the FieldSet is set to true
  • and the error prop of a child Radio is set to false
  • because of the way the component prop are merged with the object being passed as a second argument of cloneElement, the Radio will now have prop error set to true
  • So effectively the parent props are overriding the props set directly on the child. This is not good...

So, I will stop forwarding these props, and in cloneElement I will only add the fieldset-input to the classNames. This way we have a clearer separation of responsibility.

valid,
warning,
error,
required,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disabled too perhaps?

legend {
font-size: 16px;
color: ${theme.default};
margin: 0 0 ${spacers.dp12};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using the four-value sequence is preferable from a expressive perspective: 0 0 ${spacers.dp12} 0

content: '*';
}

legend.valid {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Option:

fieldset.valid > legend { ... }

I prefer yours though.

flex-direction: column;
}

div > :global(.fieldset-input) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is awkward that the FieldSet adds spacing to form components.

If we have some components within a FieldSet and some outside, the fields are going to have different margins solely based on the position in the hierarchy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could also happen the, due to a different specificity, the margin applied here will be ignored.
(I didn't think about that yesterday, when @HendrikThePendric and I were talking about this)

But specificity is another good reason not to interfere with a component's style but wrap it with another element instead (of course we could still have collapsing margins, so if the inner element has a bigger margin, that one will win, be we won't have 0-margin values anymore)

Copy link
Contributor

@varl varl Aug 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although the name FormControl might be a bit clunky, the function of it is perfect for this. Field would be an excellent name:

  <Field>
    <Input
      label="text"
    />
    <Help>text</Help>
  </Field>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that component would be an internal wrapper inside FieldSet anyways,
so I have no objections to Field, but I think FieldWrap is more accurate.

Copy link
Contributor

@varl varl Aug 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that component would be an internal wrapper inside FieldSet anyways,
so I have no objections to Field, but I think FieldWrap is more accurate.

That doesn't address the problem that components inside FieldSet are rendered different solely due to the fact that they are put inside a FieldSet component:

image

<>
    <Input value="This value is valid" valid label="A valid thing" />
    <Help valid>Foobar</Help>

    <FieldSet label="Choose something">
        <Radio
            onChange={onChange}
            name="radio"
            value="first"
            label="First"
        />
        <Radio
            onChange={onChange}
            name="radio"
            value="second"
            label="Second"
            checked
        />
        <Radio
            onChange={onChange}
            name="radio"
            value="third"
            label="Third"
        />
    </FieldSet>
    <Input value="This value is invalid" error label="An invalid thing" />
    <Help valid>Foobar</Help>
</>

We could wrap every input in a FieldSet:

<FieldSet>
    <Input value="This value is invalid" error label="An invalid thing" />
    <Help valid>Foobar</Help>
</FieldSet>

But that looks a bit funky unless we add stacked:

image

With stacked:

image

Still not perfect...

If we use the FormControl component though:

image

<>
    <FormControl>
        <Input value="This value is valid" valid label="A valid thing" />
        <Help valid>Foobar</Help>
    </FormControl>

    <FieldSet label="Choose something" stacked>
        <FormControl>
            <Radio
                onChange={onChange}
                name="radio"
                value="first"
                label="First"
            />
        </FormControl>

        <FormControl>
            <Radio
                onChange={onChange}
                name="radio"
                value="second"
                label="Second"
                checked
            />
        </FormControl>

        <FormControl>
            <Radio
                onChange={onChange}
                name="radio"
                value="third"
                label="Third"
            />
        </FormControl>
    </FieldSet>

    <FormControl>
        <Input value="This value is invalid" error label="An invalid thing" />
        <Help valid>Foobar</Help>
    </FormControl>
</>

If we go from stacked on the group of radio controls to inline, then the margin-right is gone too, so that would need to be sorted.

It is very explicit, it gets rid of the React.Children.map and React.cloneElement and just renders the children as they are defined:

<fieldset className={cx(className)}>
    {label && (
        <legend className={cx({ valid, warning, error, required })}>
            {label}
        </legend>
    )}
    <div className={cx({ stacked })}>
        {children}
    </div>
    <style jsx>{styles}</style>
</fieldset>

These are very low-level components, and will not be used directly in "real" forms, but rather always use a molecule perhaps defined in ui-forms, so a realistic form could look like:

<InputField label="" help="" value="" />
<InputField label="" help="" value="" valid />

<FieldSet stacked>
  <RadioField label="" value="" />
  <RadioField label="" value="" />
  <RadioField label="" value="" />
</FieldSet>

<InputField label="" help="" value="" error />
<CheckboxField label="" value="" help="" />

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is awkward that the FieldSet adds spacing to form components.

I think this is quite a good point, however, this thread is making me think that we actually need to stop looking at the code and the components we have at this point in time. Instead we should have a broader discussion about the components we need to a) layout form-fields, and b) build inputs that are composed of several components.

To explain why I think this, I'll give a short summary on how we got here in the first place:

  1. I was working on the RadioGroup component in ui-forms, and I realised it needed some styled elements:
    1. Some sort of text label to go above the radio inputs, with some margin
    2. Some spacing between the Radios, and support for stacked and inline
    3. I needed some sort of wrapper component, so the each form component in ui-forms would have a root component with some spacing.
  2. We decided ui-forms should contain no styling, so we should introduce helper components in ui-core. Still fully on board with that.
  3. Some of these helper components have gone through a full-on Pokemon evolution by now. We started with a RadioGroup (which was meh), which then evolved into a ToggleGroup (better, but still had quite a narrow scope and the ToggleGroup.Label component was awkward), and that then evolved into the FieldSet component.
  4. This FieldSet component makes a lot of sense, and is nice and generic. And the fact that such a generic component currently adds spacing to form components is indeed fishy.... So I would agree we should probably remove this behaviour.....
  5. However.... Now we've gotten to a point where we have a nice new FieldSet component, which makes a lot of sense conceptually, but I don't have a use-case for at the moment. And at the same time, I am still not able to compose the ui-forms RadioGroup from a bunch of ui-core components, which was how this all started. So we have sort of come full circle...

I think the summary above highlights that we are currently still working out what we need. So perhaps we'd better focus on that first, and continue building stuff later.

Do you agree @varl @Mohammer5 ?

Copy link
Contributor

@Mohammer5 Mohammer5 Aug 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we've gotten to a point where we have a nice new FieldSet component, which makes a lot of sense conceptually, but I don't have a use-case for at the moment.

fielset itself is a very useful component: It enables accessibility in forms.
See: http://usability.com.au/2013/04/accessible-forms-1-labels-and-identification/

So I think we need

  1. FieldSet (which removes the default fieldset and legend styles)
  2. FormControl (which wraps 1 field row for vertical spacing; could be 1 or more fields)
  3. StackControl (which wraps 2 or more components; can be vertical or horizontal)

Edit:
The FormControl will allow any layout, while the StackControl will not

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, taking a step back and thinking about how to lay out the components is a good idea. My notes above are intended to hammer home the API design with concrete examples so we don't dig the same hole over and over again.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5. However.... Now we've gotten to a point where we have a nice new FieldSet component, which makes a lot of sense conceptually, but I don't have a use-case for at the moment. And at the same time, I am still not able to compose the ui-forms RadioGroup from a bunch of ui-core components, which was how this all started. So we have sort of come full circle...

Does not FieldSet + FormControl give you ability to compose the ui-forms::RadioGroup component?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not FieldSet + FormControl give you ability to compose the ui-forms::RadioGroup component?

I'll interfere her:
It would probably, yes. But then we couldn't use the FormControl for other inputs in ui-forms to group inputs from ui-core with Help from u-core, which is why I proposed the 3 components above.

With those 3 you could also have multiple radio groups together in 1 FieldSet, each RadioGroup separated by a FormControl

@cooper-joe
Copy link
Member

@cooper-joe could you have a look at the statuses of the FieldSet?

Could I get some clarifcation on how the statuses work?

  1. I see the status text is appended to the label, are we unable to add the standard 'error' text (under the toggle controls)?
  2. Are we able to maniuplate the background color of the FieldSet? (I'm thinking light red bg-color for error etc)

Once I get this info I will take a quick look into how to best present the statuses and provide specs, thanks!

@varl
Copy link
Contributor

varl commented Aug 27, 2019

  1. I see the status text is appended to the label, are we unable to add the standard 'error' text (under the toggle controls)?

image

<FormControl>
    <Radio
        onChange={onChange}
        name="radio"
        value="second"
        label="Second"
        checked
        error
    />
    <Help error>Foobar!</Help>
</FormControl>

Like so, or under the entire set?

  1. Are we able to maniuplate the background color of the FieldSet? (I'm thinking light red bg-color for error etc)

Yes, but need to fix some problems with the legend being rendered slightly too high, outside the background color.

@cooper-joe
Copy link
Member

  1. I see the status text is appended to the label, are we unable to add the standard 'error' text (under the toggle controls)?

image

<FormControl>
    <Radio
        onChange={onChange}
        name="radio"
        value="second"
        label="Second"
        checked
        error
    />
    <Help error>Foobar!</Help>
</FormControl>

Like so, or under the entire set?

Under the entire set, ideally.

@varl
Copy link
Contributor

varl commented Aug 27, 2019

@cooper-joe Yeah.

Inside or outside is possible:

In:
image

Out:
image

Also shows the legend bug and background-color.

@varl
Copy link
Contributor

varl commented Aug 27, 2019

Related to: dhis2/ui-forms#25

Missing form components in the ui-forms issue:

  • FieldSet: logical grouping of a set of fields with an optional label

    💭 Do statuses really make sense on a FieldSet?

  • Field: a wrapper for form components to compose a complete field molecule with spacing

  • Radio / Checkbox / Switch: could these always stack? Getting multiple columns of those elements can be solved by the app or ui-forms by using a flex container with two columns instead of using a prop to the FieldSet.

@cooper-joe
Copy link
Member

* `FieldSet`: logical grouping of a set of fields with an optional label
  > 💭 Do statuses really make sense on a `FieldSet`?

Working on the status specs has highlighted the issues with applying a status to a FieldSet. See the example below. The status/error makes a lot of sense when using the FieldSet as a grouping for toggle controls like radio buttons. However, using a FieldSet to group multiple text inputs is a different conceptual model, now the FieldSet wraps multiple inputs that all have their own validation status. This may be confusing for users if they are presented with both of these types of FieldSets in a single form.

In this example, only one of the text inputs inside the FieldSet is returning an error, but is it immediately obvious which one? I haven't tested, but I think many users would assume that all controls inside the red/bordered area were invalid. This may be a case of adjusting the design to accomodate this flexibility, but I think it's important that we make a concious decision to allow this. Is this really what we intend with the FieldSet? I am not so sure myself, and I'm leaning towards this component being a more rigid ToggleGroup.

image

@varl
Copy link
Contributor

varl commented Aug 27, 2019

@cooper-joe I agree with that assessment up to the ToggleGroup.

The FieldSet does not need to indicate any status, each component could do that on it's own:

2019-08-27-114125_837x626_scrot

This is what I expect from a generic FieldSet component.

If we want to highlight a field-set that has a problem, we could do that with a softer gray background. Or go for the red background. That could also be added as a feature later on when it is needed.

edit: What I'm proposing is that the FieldSet can be expanded on later with statuses etc. (and in a different PR), and for now it would only be for spacing and adding a label to a group of fields.

@varl
Copy link
Contributor

varl commented Aug 27, 2019

@HendrikThePendric @cooper-joe @Mohammer5 check out this diff for what I mean.

I split out the Storybook for it for readability.

This is what I want from FieldSet right now, as simple as possible.

From here we can improve it and implement statuses, etc. in a controlled way to give some time & space for designing and implementing it at a slower pace.

@netlify
Copy link

netlify bot commented Aug 27, 2019

Deploy preview for dhis2-ui-core ready!

Built with commit 0c6cbbf

https://deploy-preview-388--dhis2-ui-core.netlify.com

@cooper-joe
Copy link
Member

@HendrikThePendric @cooper-joe @Mohammer5 check out this diff for what I mean.

I split out the Storybook for it for readability.

This is what I want from FieldSet right now, as simple as possible.

From here we can improve it and implement statuses, etc. in a controlled way to give some time & space for designing and implementing it at a slower pace.

I agree with this conclusion, the FieldSet should start as simple as possible while stilll being useful. The full design/usage spec needs to be completed before decisions about component composition can be tackled. Spacing and grouping are useful right now, so I vote that we start there.

@HendrikThePendric
Copy link
Contributor Author

HendrikThePendric commented Aug 27, 2019

This PR should now be ready for final review. @Mohammer5 your review status is still "Changes requested". Could have a look if this looks OK now, and if so approve?

@varl varl requested review from Mohammer5 and varl August 27, 2019 13:05
Copy link
Contributor

@varl varl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! 👍

Thanks for bearing with the back and forth, next time we should start with the design spec. 💃

@HendrikThePendric
Copy link
Contributor Author

Thanks for bearing with the back and forth, next time we should start with the design spec. 💃

Yeah, quite a lengthy process this way... But I am very happy with the outcome and that is much more important to me. Will merge

@HendrikThePendric HendrikThePendric merged commit ce04938 into next Aug 27, 2019
@HendrikThePendric HendrikThePendric deleted the refactor/composable-radio-group branch August 27, 2019 13:13
@dhis2-bot
Copy link
Contributor

🎉 This PR is included in version 3.9.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

varl pushed a commit that referenced this pull request Sep 6, 2019
…se (#388)

* refactor(toggle-group): split into composable components and generalise

* chore(deps-dev): bump babel-eslint from 10.0.2 to 10.0.3 (#390)

* chore(deps): bump @dhis2/prop-types from 1.0.3 to 1.0.4 (#391)

* refactor(field-set): rename ToggleGroup to FieldSet and render legend

* fix(field-set): add statuses and required props + corresponding story

* refactor(fieldset): simplify the component and narrow scope (#393)

* refactor(fieldset): implement as minimalistic Legend and FieldSet
varl pushed a commit that referenced this pull request Sep 6, 2019
…se (#388)

* refactor(toggle-group): split into composable components and generalise

* chore(deps-dev): bump babel-eslint from 10.0.2 to 10.0.3 (#390)

* chore(deps): bump @dhis2/prop-types from 1.0.3 to 1.0.4 (#391)

* refactor(field-set): rename ToggleGroup to FieldSet and render legend

* fix(field-set): add statuses and required props + corresponding story

* refactor(fieldset): simplify the component and narrow scope (#393)

* refactor(fieldset): implement as minimalistic Legend and FieldSet
varl pushed a commit that referenced this pull request Nov 6, 2019
…se (#388)

* refactor(toggle-group): split into composable components and generalise

* chore(deps-dev): bump babel-eslint from 10.0.2 to 10.0.3 (#390)

* chore(deps): bump @dhis2/prop-types from 1.0.3 to 1.0.4 (#391)

* refactor(field-set): rename ToggleGroup to FieldSet and render legend

* fix(field-set): add statuses and required props + corresponding story

* refactor(fieldset): simplify the component and narrow scope (#393)

* refactor(fieldset): implement as minimalistic Legend and FieldSet
varl pushed a commit that referenced this pull request Nov 7, 2019
BREAKING CHANGE: Renames ToggleGroup to FieldSet to match intended
usage.
varl pushed a commit that referenced this pull request Nov 7, 2019
BREAKING CHANGE: Renames ToggleGroup to FieldSet to match intended
usage.
varl pushed a commit that referenced this pull request Nov 20, 2019
BREAKING CHANGE: Renames ToggleGroup to FieldSet to match intended
usage.
varl pushed a commit that referenced this pull request Nov 25, 2019
BREAKING CHANGE: Renames ToggleGroup to FieldSet to match intended
usage.
varl pushed a commit that referenced this pull request Nov 25, 2019
BREAKING CHANGE: Renames ToggleGroup to FieldSet to match intended
usage.
dhis2-bot added a commit that referenced this pull request Nov 25, 2019
# [4.0.0](dhis2/ui@v3.12.0...v4.0.0) (2019-11-25)

### Bug Fixes

* **alert-stack:** revert changes so it just uses a fixed z-index ([63b6cff](dhis2/ui@63b6cff))
* **checkbox:** align focus/blur with change and remove disabled check ([7527002](dhis2/ui@7527002))
* **checkbox,radio:** value should be optional ([#419](dhis2/ui#419)) ([05306a2](dhis2/ui@05306a2))
* **chip remove icon:** fix position cross browser ([40d86a0](dhis2/ui@40d86a0))
* **css-variables:** improve robustness and developer warnings ([#449](dhis2/ui#449)) ([352a4d1](dhis2/ui@352a4d1))
* **file-field:** consistently use FileField instead of File + fix typo ([d51b119](dhis2/ui@d51b119))
* **file-input:** adjust component names - FormControl to Field ([d31e861](dhis2/ui@d31e861))
* **file-input:** correct line height and add className prop ([c6b79d5](dhis2/ui@c6b79d5))
* **file-input:** fix Edge text overflow behavior ([2f4a1cf](dhis2/ui@2f4a1cf))
* **file-input:** implement PlaceHolder as child of FileList ([4d70143](dhis2/ui@4d70143))
* **file-input:** implement spacing between text and link via ::after el ([f4ae821](dhis2/ui@f4ae821))
* **file-input:** improve children prop-type to allow multiple files ([e7785fd](dhis2/ui@e7785fd))
* **file-input:** introduce FileList to solve spacing issues ([5faae50](dhis2/ui@5faae50))
* **file-input:** tweak CSS to fix incorrect total height ([79d8df0](dhis2/ui@79d8df0))
* **input:** align handleFocus/handleBlur with handleChange ([848d5fe](dhis2/ui@848d5fe))
* **input:** allow types specified in design-system ([29127f3](dhis2/ui@29127f3))
* **input:** correct prop-type for type ([066e468](dhis2/ui@066e468))
* **input:** remove duplicate story and improve "No label" ([#480](dhis2/ui#480)) ([0a40894](dhis2/ui@0a40894))
* **input-field:** add required `onChange` prop to all stories ([d0060bc](dhis2/ui@d0060bc))
* **input-field:** adjust focus props and label story ([#447](dhis2/ui#447)) ([43df32e](dhis2/ui@43df32e))
* **layer:** children must be a function and required ([ec75085](dhis2/ui@ec75085))
* **layer context:** simplify and correct calculations ([4a14e3f](dhis2/ui@4a14e3f))
* **layer-context:** add support for layers upon layers ([677e585](dhis2/ui@677e585))
* **prop-types:** adjust statusPropType and use custom one for AlertBar ([85d40ba](dhis2/ui@85d40ba))
* **radio:** align handleFocus/handleBlur with handleChange ([d9b6305](dhis2/ui@d9b6305))
* **select:** add missing prop types ([fc4e499](dhis2/ui@fc4e499))
* **select:** add missing tab index default ([85904e3](dhis2/ui@85904e3))
* **select:** align onfocus and onblur with other cbs ([a607f31](dhis2/ui@a607f31))
* **select:** align select with callback style changes ([456d116](dhis2/ui@456d116))
* **select:** fix overlap on specifying input width for flex children ([54a15aa](dhis2/ui@54a15aa))
* **select:** fix positioning issues ([6bd8a2b](dhis2/ui@6bd8a2b))
* **select:** fix select closing on chip removal ([b51d101](dhis2/ui@b51d101))
* **text-area:** only set height when value changes ([9ec7437](dhis2/ui@9ec7437))
* **toggle-group:** remove `.isRequired` from `value` prop ([abb790c](dhis2/ui@abb790c))
* adjust menu position after option selection ([a5b9385](dhis2/ui@a5b9385))
* correct handler usage for filterable menu ([7f53a63](dhis2/ui@7f53a63))
* export Label in index.js ([85187b9](dhis2/ui@85187b9))
* introduce layer-context to deal with overlapping elements + story ([6632093](dhis2/ui@6632093))
* use layer-context in alert-stack and drop-menu ([2caece4](dhis2/ui@2caece4))
* **select:** make filtering case insensitive ([6d997a8](dhis2/ui@6d997a8))
* **split-button:** remove unused styles ([134fd16](dhis2/ui@134fd16))
* **switch:** align handleFocus/handleBlur with handleChange ([92550c8](dhis2/ui@92550c8))
* **tab-bar:** enforce that children are instances of the Tab component ([d583188](dhis2/ui@d583188))
* **text-area:** align handleFocus/handleBlur with handleChange ([2f3ad48](dhis2/ui@2f3ad48))
* make name prop optional instead of required ([ab8f6a5](dhis2/ui@ab8f6a5))
* **switch:** change input type to checkbox because switch is not valid ([245f8bf](dhis2/ui@245f8bf))
* **toggles:** remove position relative from toggles ([a3f5e2e](dhis2/ui@a3f5e2e))

### chore

* upgrade react to support hooks ([35672e0](dhis2/ui@35672e0))
* **help:** remove `indent` props and examples from stories ([#471](dhis2/ui#471)) ([12efecb](dhis2/ui@12efecb))

### Code Refactoring

* **checkbox:** align 'on' function handlers ([53c700d](dhis2/ui@53c700d))
* **fileinput:** align 'on' function handlers ([8829eec](dhis2/ui@8829eec))
* **formcontrol:** rename to field ([#402](dhis2/ui#402)) ([b9205e1](dhis2/ui@b9205e1))
* **input:** align 'on' function handlers ([2ab28b7](dhis2/ui@2ab28b7))
* **input,textarea:** remove option to pass in number for width ([77105f2](dhis2/ui@77105f2))
* **modal:** align modal with component structure ([b276a31](dhis2/ui@b276a31))
* **modal:** remove open prop ([9da92f1](dhis2/ui@9da92f1))
* **modal:** remove unnecessary aside element wrapper ([5e39456](dhis2/ui@5e39456))
* **radio:** align 'on' function handlers ([611a394](dhis2/ui@611a394))
* **select:** update component to new design ([e810a78](dhis2/ui@e810a78))
* **splitbutton:** separate component from buttonstrip ([#396](dhis2/ui#396)) ([f24cd11](dhis2/ui@f24cd11))
* **switch:** align 'on' function handlers ([5011d6d](dhis2/ui@5011d6d))
* **tabbar:** align component structure ([e3313f3](dhis2/ui@e3313f3))
* **textarea:** align 'on' function handlers ([44ef1bf](dhis2/ui@44ef1bf))
* implement the Radio component consistently with other inputs ([8fed62f](dhis2/ui@8fed62f))
* kill the filled option for selectfield and inputfield ([#427](dhis2/ui#427)) ([e0eabdb](dhis2/ui@e0eabdb))
* toggle input components ([b51b71c](dhis2/ui@b51b71c))
* **select,input:** drop -field suffix on components ([#389](dhis2/ui#389)) ([eb104f5](dhis2/ui@eb104f5))
* **toggle-group:** split into composable components ([#388](dhis2/ui#388)) ([e4beb91](dhis2/ui@e4beb91))

### Documentation

* introduce user docs ([#397](dhis2/ui#397)) ([c3bc557](dhis2/ui@c3bc557))

### Features

* **field:** add className prop ([7565d59](dhis2/ui@7565d59))
* **file-field:** introduce FileField component ([0423f62](dhis2/ui@0423f62))
* **file-input:** add disabled prop and button sizes ([066538f](dhis2/ui@066538f))
* **input atom:** add ellipsis to overflowing text ([56ce804](dhis2/ui@56ce804))
* **label:** add className prop ([8526560](dhis2/ui@8526560))
* **modal:** add className prop ([6c231d6](dhis2/ui@6c231d6))
* **node:** add className prop to node ([1468e35](dhis2/ui@1468e35))
* **screencover:** add transparent prop ([90a5881](dhis2/ui@90a5881))
* **select:** add input max height prop ([75555b3](dhis2/ui@75555b3))
* **select:** add inputWidth property to control width ([9eefe22](dhis2/ui@9eefe22))
* **status-icon:** add `info` and `defaultTo` props ([8144311](dhis2/ui@8144311))
* **tab components:** add className props ([480f538](dhis2/ui@480f538))
* **textarea:** introduce TextArea and TextAreaField with docs and stories ([#456](dhis2/ui#456)) ([0e73d7a](dhis2/ui@0e73d7a))
* **theme:** expose spacers, elevations and layers constants ([76f34ba](dhis2/ui@76f34ba))

### BREAKING CHANGES

* **modal:** Removed the aside element wrapper
* **modal:** Removing the "open" prop from the Modal.
* **input,textarea:** Input and TextArea now requires the input width
override to be passed in as a string.
* Now requires React >= 16.8.
* **fileinput:** `onChange` is called with two parameters:
First parameter an object with properties for `checked`, `name`, and
`value`.
The second is the React `event` object.
* **textarea:** `onChange` is called with two parameters:
First parameter an object with properties for `checked`, `name`, and
`value`.
The second is the React `event` object.
* **input:** `onChange` is called with two parameters:
First parameter an object with properties for `checked`, `name`, and
`value`.
The second is the React `event` object.
* **checkbox:** `onChange` is called with two parameters:
First parameter an object with properties for `checked`, `name`, and
`value`.
The second is the React `event` object.
* **radio:** `onChange` is called with two parameters:
First parameter an object with properties for `checked`, `name`, and
`value`.
The second is the React `event` object.
* **switch:** `onChange` is called with two parameters:
First parameter an object with properties for `checked`, `name`, and
`value`.
The second is the React `event` object.
* **tabbar:** This replaces the need to nest a TabBar in a ScrollBar,
and instead allows `TabBar.propTypes.scrollable` to toggle if a TabBar
is scrollable.
* **tabbar:** This deprecates external use of ScrollBar.
* **modal:** This deprecated use of Modal.Actions. Instead, use
ModalActions.
* **modal:** This deprecated use of Modal.Content. Instead, use
ModalContent.
* **modal:** This deprecated use of Modal.Title. Instead, use
ModalTitle.
* **tab-bar:** TabBar will now only accept Tab instances
* **select:** Select deprecated in favor of the SingleSelect, refer
to the docs for the API.
* **select:** SelectField deprecated in favor of SingleSelectField,
see the docs for the API.
* **select:** The new Select components do not accept a standard HTML `option`
element, instead they require use of SingleSelectOption, MultiSelectOption,
or a component with a matching API.
* **select:** The Select's `onChange` no longer returns a standard `Event.target`,
instead returns the selected Object with properties: `label` and
`string`, or an array of those for the MultiSelects
* **select:** The Selects all require a selected prop, instead of a value.
Where selected is an object with a label and a value string, or an array of
those for the MultiSelect.
* **select:** Since the Selects do not use a native input element, the name
prop has been dropped from the Select components.
* The `icon` and `required` props have been removed from
the Checkbox and Switch. For Switch, the `label` prop has become
required.
* RadioGroup has a new implementation and drops the
following props: label, inline, options, and helpText.
* The `icon` and `required` props have been removed from the Radio component and the `value` and `label` props have become required.
* **help:** Removes indent prop from Help. Use className to
override if necessary.
* Remove the Filled field style for SelectField and
InputField.
* MenuItem value prop is more strict, requires String
instead of any.
* **formcontrol:** Renames FormControl to Field.
* **splitbutton:** remove the `compact` prop from buttonstrip
* **toggle-group:** Renames ToggleGroup to FieldSet to match intended
usage.
* **select,input:** **InputField** renamed to **Input**

**SelectField** renamed to **Select**

* chore: trigger netlify
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants