Einride Frontend Style Guide
Most Einride code styles are enforced automatically by using
ESLint together with
@einride/eslint-plugin
,
Prettier together with
@einride/prettier-config
and
TypeScript together with
@einride/tsconfig
. Some code styles, however,
can't (or are not yet) enforced automatically. Those styles are described in this document.
Component design
- Prefer type
ReactNode
tostring
. Fragments allow markup and variables by natural JSX flow and is strictly more flexible.
// bad
`Button is clicked ${count} times`
// good
<>Button is clicked {count} times</>
// bad
<Input
label="How do I make parts of this string bold?!"
/>
// good
<Input
label={<>This is <b>way</b> more flexible!</>}
/>
- Use absolute imports, which can be achieved by setting
"baseUrl": "src"
intsconfig.json
. This enables moving files without superflous refactoring of import paths.
// bad
import { useEinride } from "../../../../../../../hooks/useEinride"
// good
import { useEinride } from "hooks/useEinride"
- Use formatting components when formatting raw data like distances or emissions for human readability. It enables changing format or enabling localization in one place rather than wherever it's used.
// bad
<p>The weight of the Pod is 1000 kg.</p>
// good
<p>The weight of the Pod is <Weight kg={1000} />.</p>
-
There's no silver bullet rule for when a part of the UI should be separated into a component of its own. However, when a part of the UI contains isolated state, it's often a good idea to think about making that UI a component and colocating its state with it.
-
Here's a VS Code snippet for creating a new component according to the style guide:
"New React component according to Einride style guide": {
"prefix": "nc",
"body": [
"interface ${TM_FILENAME_BASE}Props {",
" $1",
"}",
"",
"export const $TM_FILENAME_BASE = ({$2}: ${TM_FILENAME_BASE}Props): React.JSX.Element => {",
" return <>$0</>",
"}",
""
]
},
Project file structure
All React projects should default to this directory structure:
src/
|––assets/
|––components/
|––contexts/
|––hooks/
|––lib/
|––pages/
|––types/
assets/
Project wide media files.
components/
Root directory for all React components. Structure inside this directory can vary depending on needs.
contexts/
Project wide React contexts.
hooks/
Project wide React hooks.
lib/
Project wide utility and setup files. For example theming and API utilities.
pages/
React components intended to fill a viewport, tightly coupled to a specific URL path.
types/
Project wide types.
File naming
- Use
UpperCamelCase.tsx
for React components and use the same name for the exported component. - Use
lowerCamelCase.ts
for TypeScript files that don't contain JSX. - Use
useHook.ts
for React hooks and use the same name for the exported hook. - Don't use file names like
utils.ts
as they easily become dumps for random functions. Prefer semantic names likesort.ts
for a group of sorting utility functions orsortNames.ts
if only one sorting utility is exposed.