Component architecture guidelines
These are the guidelines we strive to follow when creating components
#Self encapsulating
By default, components should not affect outward, only inward. That means a component only has an effect on itself and its children, not its siblings or parents. An example for this are margins on the component itself, which should be avoided because margins affect outward. Instead, components should use padding, for spacing itself and its children.
Current known violators:Button might be the exception to the rule, the other two are planned to be fixed.
#Controlled
Components should in general be controlled, i.e. have data provided via props and provide event for when said data should be changed. For example in InputField
the current value
is provided via props, and the onChange
property should be used by the parent to change the value
property accordingly.
A larger example could be Table
, where all the data is provided via props and events such as onSort
is used to control changes to the data.
#Composable
When possible try to expose meaningful sub parts of a component. This allows edge cases to reuse the majority a component when diverging from the happy path.
An example of this is Card.Header
which is used to render the upper part of a card. By being exposed as a sub component instead of being a property on Card
it allows the user easier use a modified version. Perhaps there is a case where we want a drag and dropable card and the 'drag-zone' should be the header. With this design it is hopefully possible to make a new sub component DragableCardHeader
that composes Card.Header
with the added functionality while keeping the look and feel of the original, such that when it is updated in the future this will update with it. In general it should be easy to build the common/default case, but possible to deviate with as much reuse as possible.