@@ -12,12 +12,12 @@ ES6 or TypeScript.
12
12
### General
13
13
14
14
#### Write useful comments
15
- Comments that explain what some block of code does are nice; they can tell you something in less
15
+ Comments that explain what some block of code does are nice; they can tell you something in less
16
16
time than it would take to follow through the code itself.
17
17
18
- Comments that explain why some block of code exists at all, or does something the way it does,
19
- are _ invaluable_ . The "why" is difficult, or sometimes impossible, to track down without seeking out
20
- the original author. When collaborators are in the same room, this hurts productivity.
18
+ Comments that explain why some block of code exists at all, or does something the way it does,
19
+ are _ invaluable_ . The "why" is difficult, or sometimes impossible, to track down without seeking out
20
+ the original author. When collaborators are in the same room, this hurts productivity.
21
21
When collaborators are in different timezones, this can be devastating to productivity.
22
22
23
23
For example, this is a not-very-useful comment:
@@ -55,22 +55,22 @@ do this:
55
55
```
56
56
57
57
#### Prefer small, focused modules
58
- Keeping modules to a single responsibility makes the code easier to test, consume, and maintain.
59
- ES6 modules offer a straightforward way to organize code into logical, granular units.
58
+ Keeping modules to a single responsibility makes the code easier to test, consume, and maintain.
59
+ ES6 modules offer a straightforward way to organize code into logical, granular units.
60
60
Ideally, individual files are 200 - 300 lines of code.
61
61
62
- As a rule of thumb, once a file draws near 400 lines (barring abnormally long constants / comments),
63
- start considering how to refactor into smaller pieces.
62
+ As a rule of thumb, once a file draws near 400 lines (barring abnormally long constants / comments),
63
+ start considering how to refactor into smaller pieces.
64
64
65
65
#### Less is more
66
- Once a feature is released, it never goes away. We should avoid adding features that don't offer
67
- high user value for price we pay both in maintenance, complexity, and payload size. When in doubt,
68
- leave it out.
66
+ Once a feature is released, it never goes away. We should avoid adding features that don't offer
67
+ high user value for price we pay both in maintenance, complexity, and payload size. When in doubt,
68
+ leave it out.
69
69
70
- This applies especially so to providing two different APIs to accomplish the same thing. Always
70
+ This applies especially so to providing two different APIs to accomplish the same thing. Always
71
71
prefer sticking to a _ single_ API for accomplishing something.
72
72
73
- ### 100 column limit
73
+ ### 100 column limit
74
74
All code and docs in the repo should be 100 columns or fewer. This applies to TypeScript, SCSS,
75
75
HTML, bash scripts, and markdown files.
76
76
@@ -81,12 +81,12 @@ Avoid `any` where possible. If you find yourself using `any`, consider whether a
81
81
appropriate in your case.
82
82
83
83
For methods and properties that are part of a component's public API, all types must be explicitly
84
- specified because our documentation tooling cannot currently infer types in places where TypeScript
84
+ specified because our documentation tooling cannot currently infer types in places where TypeScript
85
85
can.
86
86
87
87
#### Fluent APIs
88
88
When creating a fluent or builder-pattern style API, use the ` this ` return type for methods:
89
- ```
89
+ ``` ts
90
90
class ConfigBuilder {
91
91
withName(name : string ): this {
92
92
this .config .name = name ;
@@ -95,13 +95,39 @@ class ConfigBuilder {
95
95
}
96
96
```
97
97
98
+ #### RxJS
99
+ When dealing with RxJS operators, import the operator functions directly (e.g.
100
+ ` import "rxjs/operator/map" ` ), as opposed to using the "patch" imports which pollute the user's
101
+ global Observable object (e.g. ` import "rxjs/add/operator/map" ` ):
102
+
103
+ ``` ts
104
+ // NO
105
+ import ' rxjs/add/operator/map' ;
106
+ someObservable .map (... ).subscribe (... );
107
+
108
+ // YES
109
+ import {map } from ' rxks/operator/map' ;
110
+ map .call (someObservable , ... ).subscribe (... );
111
+ ```
112
+
113
+ Note that this approach can be inflexible when dealing with long chains of operators. You can use
114
+ the ` FunctionChain ` class to help with it:
115
+
116
+ ``` ts
117
+ // Before
118
+ someObservable .filter (... ).map (... ).do (... );
119
+
120
+ // After
121
+ new FunctionChain (someObservable ).call (filter , ... ).call (map , ... ).call (do , ... ).execute ();
122
+ ```
123
+
98
124
#### Access modifiers
99
125
* Omit the ` public ` keyword as it is the default behavior.
100
126
* Use ` private ` when appropriate and possible, prefixing the name with an underscore.
101
127
* Use ` protected ` when appropriate and possible with no prefix.
102
- * Prefix * library-internal* properties and methods with an underscore without using the ` private `
128
+ * Prefix * library-internal* properties and methods with an underscore without using the ` private `
103
129
keyword. This is necessary for anything that must be public (to be used by Angular), but should not
104
- be part of the user-facing API. This typically applies to symbols used in template expressions,
130
+ be part of the user-facing API. This typically applies to symbols used in template expressions,
105
131
` @ViewChildren ` / ` @ContentChildren ` properties, host bindings, and ` @Input ` / ` @Output ` properties
106
132
(when using an alias).
107
133
@@ -114,14 +140,14 @@ All public APIs must have user-facing comments. These are extracted and shown in
114
140
on [ material.angular.io] ( https://material.angular.io ) .
115
141
116
142
Private and internal APIs should have JsDoc when they are not obvious. Ultimately it is the purview
117
- of the code reviwer as to what is "obvious", but the rule of thumb is that * most* classes,
118
- properties, and methods should have a JsDoc description.
143
+ of the code reviwer as to what is "obvious", but the rule of thumb is that * most* classes,
144
+ properties, and methods should have a JsDoc description.
119
145
120
146
Properties should have a concise description of what the property means:
121
147
``` ts
122
148
/** The label position relative to the checkbox. Defaults to 'after' */
123
149
@Input () labelPosition : ' before' | ' after' = ' after' ;
124
- ```
150
+ ```
125
151
126
152
Methods blocks should describe what the function does and provide a description for each parameter
127
153
and the return value:
@@ -145,7 +171,7 @@ Boolean properties and return values should use "Whether..." as opposed to "True
145
171
146
172
##### General
147
173
* Prefer writing out words instead of using abbreviations.
148
- * Prefer * exact* names over short names (within reason). E.g., ` labelPosition ` is better than
174
+ * Prefer * exact* names over short names (within reason). E.g., ` labelPosition ` is better than
149
175
` align ` because the former much more exactly communicates what the property means.
150
176
* Except for ` @Input ` properties, use ` is ` and ` has ` prefixes for boolean properties / methods.
151
177
@@ -169,25 +195,25 @@ The name of a method should capture the action that is performed *by* that metho
169
195
### Angular
170
196
171
197
#### Host bindings
172
- Prefer using the ` host ` object in the directive configuration instead of ` @HostBinding ` and
173
- ` @HostListener ` . We do this because TypeScript preserves the type information of methods with
198
+ Prefer using the ` host ` object in the directive configuration instead of ` @HostBinding ` and
199
+ ` @HostListener ` . We do this because TypeScript preserves the type information of methods with
174
200
decorators, and when one of the arguments for the method is a native ` Event ` type, this preserved
175
- type information can lead to runtime errors in non-browser environments (e.g., server-side
176
- pre-rendering).
201
+ type information can lead to runtime errors in non-browser environments (e.g., server-side
202
+ pre-rendering).
177
203
178
204
179
205
### CSS
180
206
181
207
#### Be cautious with use of ` display: flex `
182
- * The [ baseline calculation for flex elements] ( http://www.w3.org/TR/css-flexbox-1/#flex-baselines )
183
- is different than other display values, making it difficult to align flex elements with standard
208
+ * The [ baseline calculation for flex elements] ( http://www.w3.org/TR/css-flexbox-1/#flex-baselines )
209
+ is different than other display values, making it difficult to align flex elements with standard
184
210
elements like input and button.
185
211
* Component outermost elements are never flex (block or inline-block)
186
212
* Don't use ` display: flex ` on elements that will contain projected content.
187
213
188
214
#### Use lowest specificity possible
189
- Always prioritize lower specificity over other factors. Most style definitions should consist of a
190
- single element or css selector plus necessary state modifiers. ** Avoid SCSS nesting for the sake of
215
+ Always prioritize lower specificity over other factors. Most style definitions should consist of a
216
+ single element or css selector plus necessary state modifiers. ** Avoid SCSS nesting for the sake of
191
217
code organization.** This will allow users to much more easily override styles.
192
218
193
219
For example, rather than doing this:
@@ -224,12 +250,12 @@ md-calendar {
224
250
The end-user of a component should be the one to decide how much margin a component has around it.
225
251
226
252
#### Prefer styling the host element vs. elements inside the template (where possible).
227
- This makes it easier to override styles when necessary. For example, rather than
253
+ This makes it easier to override styles when necessary. For example, rather than
228
254
229
255
``` scss
230
256
the-host-element {
231
257
// ...
232
-
258
+
233
259
.some-child-element {
234
260
color : red ;
235
261
}
@@ -267,4 +293,4 @@ When it is not super obvious, include a brief description of what a class repres
267
293
268
294
// Portion of the floating panel that sits, invisibly, on top of the input.
269
295
.md-datepicker-input-mask { }
270
- ```
296
+ ```
0 commit comments