# Coding guidelines
Below you can find rules that needs to be applied into every component from Storefront UI to ensure that they are highly customizable, follow common format and coding standards.
# Coding conventions
The good news is that for basic coding, we have
prettier run automatically on each commit made. Besides we do have
eslint check enabled, so you can know exactly where you code doesn't fit our conventions.
In general, this is an open source project, hence:
- Readability is extremly important. Please consider the next random developer who will read your code, and keep it simple for them.
- No complex logic in
templateview. If there is, please use
# Design patterns
We use atomic design concept for grouping components (without templates and pages).
In general, there are three groups of components:
- Atoms - Atoms are the most basic and abstract components for building other components, such as color palletes, icons, button, input, etc.
- Molecules - Molecules are components built from groups of atoms bonded together, take on their own properties and serve as the backbone of the design systems. Some good examples are a banner, gallery, menu item, etc.
- Organisms - Organisms are complex and distinct components built from groups of molecules joined together, such as header, grid, accordions, etc.
IDENTIFY COMPONENT GROUP
Identifying component group is not easy, hence we save you the trouble. In the component request issue, the group directory of the component will be mentioned as part of the requirements.
# Component rules
# Naming convention
We follow Pascal Case for component naming and with a prefix
Sf - hence the naming formula will be:
# Component's file structure
- Each component should be divided into parts, which are separate files. Each file should be named in the format
./<ComponentName>/ |__Sf<ComponentName>.vue |__Sf<ComponentName>.html |__Sf<ComponentName>.js |__Sf<ComponentName>.spec.ts |__Sf<ComponentName>.stories.js
The following file should be located in the same component's directory:
.vue- imports relevant
.scssfor CSS styling part for building the component.
<script src="./SfIcon.js"></script> <template lang="html" src="./SfIcon.html"></template> <style lang="scss"> @import "~@storefront-ui/shared/styles/components/SfIcon.scss"; </style>
html- template markup
spec.ts- unit test for component, in TypeScript.
stories.js- Storybook stories for the component.
For the purpose of sharing our component design between projects, all the
.scss files of the components will not reside within each component's directory, but will be in
shared/styles/components/. Naming convention is the same as above.
# CSS Rules
# CSS Naming convention
We strictly follow BEMs for naming SCSS modifiers and CSS classes. And the CSS class names should match
Keep up to 2 BEM levels (elements) at most.
# CSS structure
- Use flexbox
- Always import a global variables at the top.
- Start with mobile view and write mobile-first CSS. It means that media queries should be only for a desktop view.
- DO NOT use scoped styles.
- Use global css variables whenever it's possible.
- Component-specific SCSS variables should be at the top of the component
Use use global SCSS variables inside SCSS variables for common properties like colors. All the global variables are found in
- Properties that may broke the design in future changes shouldn't be customizable.
A safe set of properties to customize are:
padding (not always),
margin (not always),
align-content (not always),
- Provide CSS modifiers for most common modifications. (
- DO NOT use any outer positioning for components (like outer margins). The way they're positioned in layout should be determined in outer environment.
SAMPLE CSS FILE
Here you can find an example of properly styled component with all rules applied.
# Template rules
- HTML should be semantic and not tied to CSS implementation. Total repalcement of CSS should be possible without using semantic meaning of markup.
- We use slots and props for content composition.
- Props should be used to fulfil most common use case
- Instead of providing multiple props and configurations for different use cases try to add slots with general usage
- Slots are also meant to be used for markup replacement. In other words every default markup should be replacable with slots.
- Always provide proper slot-scope. For example when we have pagination component with slot
nextallowing to replace arrow to next page we would like to provide things like
canGoFurthervariable. Then if someone will choose to replace slot content with his/her own it's much easier to know how to keep same behavior.
- One slot is usually a single BEM element.
- DO NOT use props for setting properties that can be set by css (except for background images).
- Provide a default slot (usually empty) for a full customization support.
Try to make components as customizable as possible without complicating them. Think about the parts that are usually customized and allow simple way to change their look.
# Unit tests
The minimum set of tests should contain component:
- External API:
- Internal API:
# Stories for Storybook
Component stories should contain at least these following stories:
- Default called
basicfor all props, with props and CSS modifiers fillable as knobs.
- One for every customisable
slotin the component
A good example is SfBanner stories.
You can learn more about Storybook syntax and how to use here.
Check our storybook for examples.