Creating Common Loading Component in SUSI.AI

A circular loading component appears whenever an asynchronous event takes time on the front-end, to show the user that content is yet to be fetched and processed.

Creating Common Loading component eased the process of handling circular loading alignment. Using common loader decreased code repetition. There were major cases for loader component, mobile view, and desktop view.

Why Styled-components for SUSI.AI?

  • Painless maintenance
  • On-demand CSS injection: The components being rendered in the page are kept on track and only those component’s styles are injected into the DOM. If we combine react-loadable or some other code splitting, the app becomes really performant.
  • Styled components generate their own class name like sc-g3h4h6 and add it as an attribute to DOM, which avoids class name overlaps and misalignments.
  • Styled components are easier to detect as they can be detected by linter and husky. Whereas, static CSS files are not detected, which leads to dead code in the codebase and make them hard to manage. 
  • Simple dynamic styling: adapting the styling of a component based on its props, without having to manually manage dozens of classes.
  • Automatic vendor prefixing
  • Reuse, Reduce code written for CSS
  • Supports media queries, which makes creating a responsive PWA easier

 Let’s have a look at it’s implemented.

Code Integration

const Container = styled.div`
 display: flex;
 align-items: center;
 justify-content: center;
 ${props =>
   props.height
     ? css`
         height: ${props => props.height + 'rem'};
         @media (max-width: 512px) {
           height: ${props =>
             props.height > 20
               ? props.height - 15 + 'rem'
               : props.height + 'rem'};
         }
       `
     : css`
         margin: 19rem 0;
         height: 100%;
         @media (max-width: 512px) {
           margin: 14rem 0;
         }
       `}
`;

const CircularLoader = ({ height = 'auto', color = 'primary', size = 64 }) => {
 return (
   <Container height={height}>
     <CircularProgress color={color} size={size} />
   </Container>
 );
};

components/shared/CircularLoader.js

The CircularLoader component by default should acquire size 64 width and size, and color primary i.e. SUSI.AI blue color.

The container created using styled component, by default should be horizontally and vertically centered. This is used to handle the case where the content takes the whole width and height(100%) of page. 

If we want the container to be of specific height(lesser than the page in which the Loader is being rendered), we pass in height props.

For handling the mobile views, in case of height, 100%, margin-top and margin-bottom are reduced by 5rem.

In case of height passed in through component, check if the height is greater(than 20) so that the mobile view user can see the footer as well, reduce height by 15rem. If the height is lesser than 20rem, the footer is in the viewport.

Before PR, let’s have a look at how the Loader was rendered inside component:

{loading ? (
  <LoadingContainer>
    <CircularProgress size={64} />
  </LoadingContainer>
 ) : (
   ...
 )}

Using Common shared loader,

{loading ? <CircularLoader height={27} /> : ...

Settings/Settings.react.js

Adding styled component across the SUSI.AI web app proved to be of great help, the mobile views were easily made using media queries. Components positioning logic could be changed based on props, and most importantly, styled-components could be reused and were much easier to manage and maintain than static CSS classes or inline styles.

However, for other cases like when single or less number of styles were applied, maintaining everything using styled component proved to be additional overhead. A combination of inline styles and styled-components would be apt depending on the nature of style. 

Resources

Tags

SUSI.AI, FOSSASIA, GSoC19, styled-components, SUSI.AI Chat

Close Menu