Skip to content

Fiori Next Style Guide

g-cheishvili edited this page Feb 15, 2022 · 6 revisions

In general we follow Angular styleguide, but there are specific reccomendations from our side too. If you can not find rules for your topic of interest on this page, you can refer to Angular styleguide for help.

Approach to development

Class inheritance and common behaviors

Avoid inheritance of classes. Especially marking parent properties with angular's decorators(@Input, @Output, @HostListener, @HostBinding...). If there is some functionallity, that is needed in more than one component and can be described as "common behavior", extract it into the separate directive. In general approach development with "composition over inheritance". If you need data from that extracted directive, you can inject that directive into the main component using Lightweight injection tokens.

References to classes

Avoid referencing to concrete classes from components/directives if those classes are not tightly related to each other and user will always use both of them together. Use Injection tokens instead of directly referencing classes. This will make testing easier, as well as will make code more atomic. Depend on interfaces and abstractions instead of implementation.

Native elements

Use as much native elements in your development as you can. Browsers are smart, very smart. They have their own way of dealing with most native elements. So instead of replacing them(native tags, elements) and trying to fill the void of incomplete functionallity, enhance existing with added features. Yes, we can not always reuse native tags and that is ok, but do not try to replace button with my-button-component, because side effects sometimes are not visible from the first glance.

Setter/Getter vs. ngOnChanges

If you have to react on one or two input changes, go ahead and use @Input with property setter and getter, but if you rely on more than that, you should probably consider moving that logic to ngOnChanges.

Generic components, directives, services, functions and etc.

For example if you have select component, which has to receive list of items. Consider writing class with generic type. If class is called MySelectComponent, write MySelectComponent<ValueType>. Then in @Input and @Output properties you can use that type as needed. That will help a lot to the end users with autogenerations and generally ensure more type-safed environment.

Components

HTML and CSS files

If your component HTML contains up to 3 lines of code, feel free to include into the template metadata, otherwise, please create separate HTML file for component.

If your component CSS contains up to 15 lines of code, feel free to include into the styles metadata, otherwise, please create separate CSS file for component.

We use SASS for styling our components, so always use scss extension styles when writing component CSS files.

Avoid at all costs writing custom CSS in component styles, those rules should be extracted to the fundamental-styles repository. Create PR there and continue working on features for ngx.

Selectors

All of the components should have prefix fn. Component selectors always should be in dash-case. Even if selector is attribute selector(e.g. li[fn-list-item]). If component may have custom selector and attribute selector, then you can freely separate them using ,, but in such cases, respect dash-case rule. So in given example component selector would be fn-list-item, li[fn-list-item]. Pay attention that custom selector is moved to the attribute.

Inputs and Outputs metadata

In general we avoid using inputs metadata, but in case your component class extends other base class, which has inputs and outputs described, it is better to list those inputs and outputs to the child component class metadata, because that way it becomes easier to find out what inputs and outputs component has without looking into the parent classes.

Host metadata

If your component has many @HostBindings, then move them to host metadata, so that they are accessible and visible from one place.

Change detection

Prefer change detection OnPush over Default. Prefer markForCheck() if your logic does not require immediate feedback.

Directives

Selector

Always use camelCase and prefix them with fn. If you have some atomic directive, lets say fnHoverable, then allow user to disable that feature by passing [fnHoverable]="false" property. This can be achieved by adding @Input() fnHoverable: boolean to your directive and then adding appropriate logic for turning on and off the feature.

Inputs and outputs - TBD

Structural directives topic - TBD

Clone this wiki locally