Adventure Product UI Style Guide
Technical Story: PT1-117
Context and Problem Statement¶
As the team grows, inconsistency with how we create and use UI components has begun to sneak in. Whilst there's clearly a tolerable level and we don't want to hamper our agility, allowing a free-for-all (particularly with Peter on the team) will likely create a situation where it's harder to make substantial changes and alter conventions later.
As a result, we'll implement the attached style guide as a reference for working specifically on the adventure product frontend.
Decision Drivers ¶
- Growing team and need to share context/conventions in writing
- Lack of clarity not only in which components to use when but also which library (e.g. we have both
mui
andstyled-components
) - Clearer framework to allow us to bring in less senior engineers
Decision Outcome¶
Keep a style guide (appended) in our ADRs, which we can update by superseding as necessary. This guide should not hamper innovation or experimentation and it's encouraged to find new patterns that are helpful and propose changes to supersede this document where they should be adopted.
Positive Consequences ¶
- Clear reference document for frontend conventions
- Shorter time to merge with fewer changes requested
- Happy Morgan
Negative Consequences ¶
- Small risk of reduced agility but should be minimal as this a guide not a rulebook
Styleguide¶
General¶
- Always prefer arrow functions vs regular or anonymous functions
- Always prefer named exports as opposed to default exports
- Use the generated types whenever possible
React component skeleton¶
React components should adhere to the following skeleton:
import React from "react";
interface PropTypes {
exampleProperty: string;
}
export const ExampleComponent: FC<PropTypes> = (props) => {
const { exampleProperty } = props;
// render
};
const SomeStyledComponent = styled.div`
color: red;
`;
Notes from the snippet above:
- PropTypes are defined separately in their own interface (not inlined in the component declaration)
- PropTypes are passed to the component using
FC
- Components are always functional components
- Any one-off customized styled components go below the component in order to not hurt readability
- Props are destructured inside the components body (not in the param declaration), it could be useful in some cases to destructure inline but only up to two parameters
Styling¶
One-off customizations¶
One-off customizations are really specific to a usecase and they are not meant to be reused. One-off customizations are done using inline css, the sx prop on mui components or styled components
- Rule of thumb
- If less than 4 css properties are specified use inline css or the
sx
prop (less pollution of the jsx) - Otherwise use a styled component to override the styling
- If less than 4 css properties are specified use inline css or the
Reusable customizations¶
- Customization of generic material ui components that are used across the app should be done in the theme
- Custom defined reusable elements should be defined as react component / styled components in the shared module
Whenever possible, components defined from mui should be preffered as opposed to defining custom reusable component
- Use one of the typographies variants from mui as opposed to defining custom labels with custom fonts
- If the typography variants do not have the specific typography you need, define a custom variant in the theme, this will allow us to have finite set of typographies mapped to the theme
- Use one of the typographies variants from mui as opposed to defining custom labels with custom fonts
Spacings¶
- Defined spacing in the app in the form of margins or paddings should be done using the theme spacing as opposed to custom one-off customized spacings
- Example:
padding: ${(props) => props.theme.mui.spacing(4)};
instead ofpadding: 30px
- This will aid the responsiveness process in the future, as well as allowing us to have consistent spacing based on some spacing factor that we define and control
- Example: