Basic Rules
- Ensure each file contains only one component.
- Utilize JSX syntax consistently for every component.
- Opt for TypeScript over JavaScript, particularly for new code, whenever feasible.
File Creation
- Adhere to
kebab-casewhen creating any files. - Always generate component files with the extension
.tsx. - Create controller files with the extension
.tsexclusively.
CMS Component Creation
-
Component Folder:
- Within the
cms-librarydirectory, create a new folder named after your theme component. This folder will store all the component’s files.
- Within the
-
Component Structure:
- Inside the component folder:
- Create a file with the same name as your component but with the
.tsxextension. This file is responsible for returning the component’s JSX code. - Create another file with the
.tsextension. This file will contain all the business logic for your component, separate from the JSX. - Create an
index.tsfile. This file will act as the entry point, potentially exporting the main component and any helper functions from the controller file.
- Create a file with the same name as your component but with the
- Inside the component folder:
-
Register the Component (parent
index.ts):- In the parent folder of
cms-library(likely namedcomponents), locate theindex.tsfile. - Edit this
index.tsfile to include an entry for your newly created component. This typically involves importing the component from its folder location and adding it to an export statement.
- In the parent folder of
cms-library.
Props
- Always use
camelCasefor prop names, orsnake-caseif the prop value is a React component.
Parentheses
Wrap JSX tags in parentheses when they span more than one line. eslint: react/jsx-wrap-multilinesMethod
Use Arrow functions to close over local variables. For repetitive tasks or functions with identical logic declared and invoked in multiple components, consider relocating them to theutils folder and exporting them from its index.
Do not use underscore prefix for internal methods of a React component.
Don’t use underscores for privacy in JavaScript components. While some
languages use underscores to mark something as private, JavaScript doesn’t have built-in privacy. All properties, even those with underscores, are accessible by anyone using your code. Treat all component properties as public and use other methods (like closures or modules) for true data encapsulation if needed.Import only top-level modules
The files inside a module are implementation details of that module. They should never be imported directly. Instead, you must only import the top-level API that’s exported by the module itself. On the other hand, a module should be able to import parent and sibling modules.Avoid export * in top level index.ts files
The exports incomponetns/index.ts, public/index.ts dictate a plugin’s public API. The public API should be carefully controlled, and using export * makes it very easy for a developer working on internal changes to export a new public API unintentionally:
Write small functions
Keep your functions short. A good function fits on a slide that the people in the last row of a big room can comfortably read. So don’t count on them having perfect vision and limit yourself to ~15 lines of code per function.Default argument syntax
Always use the default argument syntax for optional arguments:Prettier and Linting
We are gradually moving the Experro theme code base over to Prettier. All TypeScript code and some JavaScript code (check .eslintrc.js) is using Prettier to format code. We recommend you to enable running ESLint via your IDE. Whenever possible we are trying to use Prettier and linting, instead of maintaining a set of written style guide rules. Consider every linting rule and every Prettier rule to be also part of our style guide and disable them only in exceptional cases and ideally leave a comment why they are disabled at that specific place.Avoid any whenever possible
With the advent of TypeScript 3.0 and the introduction of the unknown type, there are seldom reasons to employ any as a type. Nearly all instances where any was previously used can be substituted with either a generic or unknown type (in cases where the type is genuinely unknown).
It’s advisable to consistently utilize these mechanisms over any, as they offer stricter typing and are less prone to introducing bugs in the future due to inadequate types.
If your plugin does not utilize any or if you’re initiating a new plugin, it’s recommended to enable the @typescript-eslint/no-explicit-any linting rule for your plugin via the .eslintrc.js configuration.
Use slashes for comments
Use slashes for both single line and multi line comments. Try to write comments that explain higher level mechanisms or clarify difficult segments of your code. Don’t use comments to restate trivial things.SASS files
When writing a new component, create a sibling SASS file of the same name and import directly into the top of the JS/TS component file. Doing so ensures the styles are never separated or lost on import and allows for better modularization (smaller individual plugin asset footprint). It is recommended to create a new file for component or file in that particuler comonents folder. and import it in asrc/assets/scss/app.scss for global mapping.