penx / govuk-frontend-react

govuk-frontend as React components
4 stars 2 forks source link

govuk-frontend-react

govuk-frontend as React components.

This is proof of concept, showing how govuk-frontend can be used as CSS modules via a set of React components that is published to npm, in a way that is compatible with create-react-app, Next.js, Final Form, Formik, React Router and Reach Router, with support for tree shaking and code splitting/lazy loading.

See:

https://github.com/govuk-react/govuk-react/issues/76

CSS Modules

govuk-frontend does not 100% support being used as CSS Modules, though there the potential for this to be added in future:

https://github.com/alphagov/govuk-design-system-architecture/pull/12

One aim of this project is to create a library that has all the features of govuk-react, but is powered by govuk-frontend. One of these features is path splitting or critical extraction of styles when used in a 'standard' React build system such as those used by create-react-app or next.js.

Path splitting for CSS is coming to next.js soon:

As raised in the RFC for this feature, critically extracting CSS is potentially error prone due to the potential to extract global styles. However, when using CSS Modules, next.js is able to analyse what styles are not global and extract these. As such, next.js will only provide path splitting and critical extraction for CSS Modules. This is a reasonable approach and means in order to achieve this we need to use govuk-frontend as a set of CSS Modules and then identify what is broken and perhaps manually fix it, or raise as an issue on govuk-frontend (see list of issues below).

Conventions

Common conventions used when deciding how to rewrite the nunjucks templates:

BEM

When looking at govuk-frontend BEM class names:

e.g. a class name of govuk-my-block__my-element--my-modifier implies:

e.g. a class name of govuk-radios__conditional--hidden implies:

TODO: props (modifiers) sent to component should be made available to overrding sub components (elements) - how to do this?

=> if you want to intercept the modifiers as props then provide custom elements/components (CSSinJS with styled function) => if you just want to provide className lookup then use classNames (CSS Modules)/CSSinJS with css function

BEM convention classname exceptions:

Props

Where our React prop names differ from the nunjucks macro option names.

nunjucks react
element as
attributes rest props (where appropriate)
text children (where appropriate)
html children (where appropriate)
describedBy aria-describedby

This conversion can be seen in more detail in tests/render.js (though this file needs cleaning up at time of writing).

Create React App support

Works! Including:

See https://github.com/penx/govuk-frontend-react-example

TODO:

I aim to complete the following as part of the PoC:

Other TODO:

Grey areas

Things that I'm not 100% on how to deal with:

govuk-frontend related issues