|
1 | 1 | # Hubs Frontend Development Best Practices
|
2 | 2 |
|
| 3 | +The Hubs UI is built with React, CSS Modules, and a number of other libraries. This guide is intended to get you up to speed with how we on the Hubs team write frontend code. |
| 4 | + |
| 5 | +## Javascript Style |
| 6 | + |
| 7 | +We use [Prettier](https://prettier.io/) for code formatting and a series of [ESLint](https://eslint.org/) rules for linting. |
| 8 | + |
| 9 | +Currently the only modification we have made to the default prettier config is a 120 character line width. We as a team decided that 80 characters was not enough despite the Prettier team's [strong suggestion](https://prettier.io/docs/en/options.html#print-width). |
| 10 | + |
| 11 | +You can look at our [.eslintrc.js](../.eslintrc.js) file for our linting rules. Documentation for the various rules are linked in that file. |
| 12 | + |
3 | 13 | ## React
|
4 | 14 |
|
| 15 | +Hubs underwent a major redesign in 2020 and was transitioned from React class based components to React hooks in the process. There may still be some legacy code that uses class based components, but we intend to use hooks for all evergreen code. |
| 16 | + |
| 17 | +### React Resources |
| 18 | +- [Official React Docs](https://reactjs.org/docs/getting-started.html) |
| 19 | + |
| 20 | +### Hooks |
| 21 | + |
| 22 | +If you are new to React hooks we recommend the following guides to get started: |
| 23 | +- [Official React Docs on Hooks](https://reactjs.org/docs/hooks-intro.html) |
| 24 | +- [Thinking in React Hooks](https://wattenberger.com/blog/react-hooks) |
| 25 | + |
| 26 | + |
5 | 27 | ### File / Folder Structure
|
6 | 28 |
|
7 | 29 | - Keep files relatively small
|
|
33 | 55 | - Wiring business logic to presentational components should be done in container components
|
34 | 56 | - Container components can depend on presentational components, hooks with business logic, and other container components.
|
35 | 57 | - Container components shouldn't contain html elements or their own stylesheets
|
36 |
| -- |
| 58 | + |
| 59 | +## CSS / CSS Modules |
| 60 | + |
| 61 | +Hubs uses [CSS Modules](https://github.com/css-modules/css-modules) and [SASS](https://sass-lang.com/) for styles. |
| 62 | + |
| 63 | +You should avoid global class names whenever possible and instead rely on imported classes from css modules in your code. |
| 64 | + |
| 65 | +SASS mixins, functions, etc. should generally be avoided whenever possible. They add complexity to stylesheets that makes them harder to read and understand. |
| 66 | + |
| 67 | +You should avoid nested SASS rules when possible. One major reason for using them is for [selector specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity). Another would be for programatically changing a single parent class that affects multiple child classes. Overuse of nested selectors bloats our stylesheets and should be avoided. |
| 68 | + |
| 69 | +We use "t-shirt size" class suffixes for utility classes. Follow this pattern whenever you need to specify programatic sizes. |
| 70 | + |
| 71 | +Ex. |
| 72 | +```css |
| 73 | +.button-2xs {} |
| 74 | +.button-xs {} |
| 75 | +.button-sm {} |
| 76 | +.button-md {} |
| 77 | +.button-lg {} |
| 78 | +.button-xl {} |
| 79 | +.button-2xl {} |
| 80 | +``` |
| 81 | + |
| 82 | +All CSS colors and fonts should be defined in [theme.scss](../src/react-components/styles/theme.scss). These variables are configurable in Hubs Cloud instances. In some rare cases, you may want to explicitly enforce a color that cannot be configured (Ex. black/white text for an overlay). |
| 83 | + |
| 84 | +Theme variables are imported using the `@use` keyword. This must be the first line in your `.scss` file. All variables will be namespaced with the filename. For `theme.scss` this would be `theme.$my-variable`. |
| 85 | + |
| 86 | +Ex. |
| 87 | + |
| 88 | +```scss |
| 89 | +@use '../styles/theme'; |
| 90 | +/* rest of the styles */ |
| 91 | +``` |
| 92 | + |
| 93 | +CSS styles should be written with mobile-first media queries. This means the styles in the bare class should represent those on the smallest screen and media queries should be used for styles that are different on larger screens. |
| 94 | + |
| 95 | +Ex. |
| 96 | +```scss |
| 97 | +:local(.sidebar) { |
| 98 | + position: relative; |
| 99 | + display: flex; |
| 100 | + flex-direction: column; |
| 101 | + height: 100%; |
| 102 | + background-color: theme.$white; |
| 103 | + pointer-events: auto; |
| 104 | + |
| 105 | + @media(min-width: theme.$breakpoint-lg) and (min-height: theme.$breakpoint-vr) { |
| 106 | + border-left: 1px solid theme.$lightgrey; |
| 107 | + } |
| 108 | +} |
| 109 | +``` |
0 commit comments