⚠️ dhis2/ui-core has moved to dhis2/uiThe package name (@dhis2/ui-core) is still available, and will be published from dhis2/ui.
Online docs and demos (latest master build)
These are included with apps generated with Create React App, but if you
want to use this library with the environments in .browserslistrc
you
need to polyfill the following:
- web.dom.iterable
- es6.array.fill
- es6.array.iterator
- es6.function.name
- es6.object.assign
- es6.object.keys
- es6.object.set-prototype-of
- es6.promise
- es6.regexp.match
- es6.regexp.split
- es6.string.starts-with
- es6.string.iterator
- es6.symbol
- es7.symbol.async-iterator
Make a PR from the component branch. Add a team member who can review the code and example for both LTR and RTL modes.
We use Storybook that is excellent for testing components while developing them.
yarn install
yarn start
The Storybook runs on localhost:5000.
This library follows the dhis2 code-style. There is a commit hook that will apply the code style to staged files, but if you want to do this manually during development, run:
yarn format
This library follows the commit message style defined in @commitlint/config-conventional. There is a pre-commit hook that will stop commits that don't follow the convention.
When a PR is merged to the master branch, the release process automatically starts.
It is very important that the commit that lands on master follows the conventional commit format, since that is what is used to automatically determine the next version.
Never push straight to master, always go through a PR!
Testing is done with cypress & cucumber.
-
Run
yarn cypress:run
This will run cypress and exit with either 0 or 1 -
Run
yarn cypress:open
This will open the cypress gui, which is useful for writing tests
When running yarn cypress:run
, by default no video is recorded and no
screenshot will be taken.
- Recording videos can be enabled by supplying the
CYPRESS_VIDEO=true
env var. - Taking screenshots can be enabled by supplying the
CYPRESS_SCREENSHOT=true
env var.
Sometimes it's required to add stateful stories to test certain behavior.
That's why you can add files with the following file name format: *.stories.testing.js
These stories will not be used when generating the docs storybook and can
contain more sophisticated scenarios for testing.
The best practice is that each component has styles that are scoped to that component to avoid style rules that leak out from one component and bleeds into another component.
Generally all the CSS-in-JS solutions grant this out of the box, and
this is only a problem when using global stylesheets, e.g. by importing
index.css
in an application and adding global rules to it.
There are two ways to work around the problem.
Given the following CSS:
index.css
:
div {
padding: 20px;
}
.disabled {
opacity: 0.5;
}
These styles will bleed into all components that use div
or
.disabled
and doesn't itself set those rules and win by specificity.
If a rule is not set by the component, the technique that overrides
through the use of className
still applies, it's just "softer" and
does not require !important
to counter the rules.
If the rules do something !important
, the only course of action is to
counter it with another !important
rule. Given the following CSS:
index.css
:
div {
padding: 20px !important;
}
.disabled {
opacity: 0.5 !important;
}
Now there is no way for specificity to win, and all components that use those classes or elements will inherit those rules.
By using a cascading override, the style bleed can be stopped by utilizing a wrapper element for the component, and this will cascade down to the children of the component as well. The technique allows for a workaround which does not affect the component itself, and is easily removed when the App no longer uses leaky styles.
Before:
<div>
{...}
<Component disabled />
</div>
After:
<div>
{...}
<div className="fix-container">
<Component disabled />
</div>
</div>
.fix-container .disabled {
/* will undo the overriding of global styles for this component */
opacity: 1 !important;
}
If you cannot control the CSS that bleeds into ui
components, then
you need to define a class that counters the effects of the rule, and
use the className
prop to override the global rule.
index.css
:
.fix {
opacity: 1 !important;
padding: 10px !important;
}
Pass that to the component through className='fix'
, and it should
negate the troublesome CSS. Once the global rules in the App has been
removed, it is possible to remove the className='fix'
as well. This
should be considered a temporary measure.