├── CONTRIBUTING.md
├── README.md
├── blog
├── README.md
└── patterns.md
├── coding
└── README.md
├── css
└── README.md
├── design
└── deliverables
│ ├── README.md
│ └── images
│ ├── elementcollage-cloudfour.jpg
│ └── moodboard-cloudfour.png
├── git
├── README.md
├── commit_template.txt
└── pull_request_template.md
├── javascript
├── README.md
└── vue
│ └── README.md
├── learning
└── javascript
│ └── README.md
├── npm
└── README.md
├── opensource
└── README.md
├── package-json-script-names.md
├── rituals
├── README.md
└── postmortems.md
├── testing
└── README.md
└── til
├── README.md
├── css
└── filters-and-transitions.md
├── git
└── README.md
├── js
└── README.md
└── lyza
└── README.md
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to the Guides
2 |
3 | ## Just do it on `master`...
4 |
5 | * Adding a whole new section
6 | * Adding a TIL
7 | * Trivial modifications
8 | * When it just feels right and makes sense
9 |
10 | ## Branch/PR
11 |
12 | * Ongoing substantial changes to existing sections
13 | * Adding or modifying something that warrants discussion
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Guides
2 |
3 | Conventions, processes and notes about how we do things.
4 |
5 | - **[General Coding Conventions](./coding/)**
6 | - **[CSS Guide](./css/)**
7 | - **[JavaScript Guide](./javascript/)**
8 | - [Vue Guide](./javascript/vue)
9 | - **[Design Guide](./design/)**
10 | - **[Blog Guide](./blog)**
11 | - **[Git Guide](./git/)**
12 | - **[npm Guide](./npm)**
13 | - **[Open Source Guide](./opensource)**
14 | - **[Rituals Guide](./rituals)**
15 | - **[Today I Learned](./til/)**
16 | - **[Automated Testing](./testing)**
--------------------------------------------------------------------------------
/blog/README.md:
--------------------------------------------------------------------------------
1 | # Cloud Four Blog Guide
2 |
3 |
4 |
5 | So you've decided to write for the Cloud Four blog… Congratulations! There are a few things you may want to know about how our blog works:
6 |
7 | ## Post Excerpt Field
8 |
9 | Don't miss the "Excerpt" field at the bottom of the post editing UI. By crafting a short excerpt here, it will be displayed on the post listing pages and used for social media posts. If you don't set one explicitly, one will be created using the first few sentences of your post.
10 |
11 |
12 |
13 | Note you may need to open the "Screen Options" dialogue at the top of the page to make the "Excerpt" field visible.
14 |
15 | ## Featured Image Field
16 |
17 | Similarly, don't forget the "Featured Image" field in the sidebar. If you set an image here, it will be used for social media. This image is not displayed in the post content, however, so if you want to use it as a big image at the top of your post, you'll have to do that AND set the featured image.
18 |
19 | ## Categories and Tags
20 |
21 | Wordpress has a couple tools for organizing your posts: categories and tags. In the current iteration of cloudfour.com, we primarily use categories, and rarely use tags. Here's some background context from Tyler:
22 |
23 | >In past versions of the site, a large amount of tags proved tricky to navigate. So currently, we only expose categories (though we call them "Topics") in the front-end. Sometimes we use tags as an organizational tool behind the scenes, like flagging "featured" articles for the homepage.
24 |
25 |
26 | ## WordPress Shortcodes & Classes
27 |
28 | We have a small collection of [useful shortcodes and classes](patterns.md) to apply design patterns from our [pattern library](https://cloudfour-patterns.netlify.com/patterns/utilities.html).
29 |
30 | ## Previewing
31 |
32 | Note that our blog has two preview features. The "Preview" button only works for authenticated users. The "Enable Public Preview" checkbox will give you a public URL to share with unauthenticated users.
33 |
34 | Sometimes the public preview can get stuck or cached. To reset, just uncheck the preview box and check it again.
35 |
36 | ## Publication Time
37 |
38 | Jason's favorite time is 8:30 AM Pacific Time. Before lunch on East Coast, but late enough to be what people on West Coast see it first thing when they arrive in office.
39 |
40 | ## Comments & Pingbacks
41 |
42 | We don’t have a formal policy on comment approval, but here’s Jason's general guideline:
43 |
44 | - Let the author approve comments so they have the opportunity to process and respond if they want to.
45 | - Replying to comments is up to the author. If they contribute to understanding and there is nothing else to add, don’t feel compelled to respond.
46 | - Delete comments that are spam, troll, or jerk-like behavior.
47 |
48 | ### Advice from Jason:
49 |
50 | > Despite the fact that we ask people to be kind, courteous and constructive when they submit comments on our site, when articles reach a larger audience, we will inevitably end up some with comments that start to inch into an unkind territory. It can be hard to tell how to respond. If they are blatant jerks, I’ll simply delete their comment—you don’t get to come into our house and tear the place up. Sometimes with an obviously snarky comment, I’ll ignore the sarcasm and respond to the question as if it was asked in earnest.
51 |
52 | ### Pingbacks
53 |
54 | Don't approve pingbacks. We keep the feature enabled so we can see if websites link to us, but there's not very much review in displaying them on the site, and we don't optimize for them in our design.
55 |
56 | ## Translation Requests
57 |
58 | We have received requests to translate our articles in the past, but don't have a set answer. We'll considering saying "yes," if we still get credit, a link back to our site is clearly included, and they have a demonstrable track record of respectful translations.
59 |
60 | ## Writing Advice
61 |
62 | - [Don't Feel Like an Expert? Share Anyway.](https://medium.com/@sara_ann_marie/dont-feel-like-an-expert-share-anyway-661f2f8cd038)
63 |
64 | > Too many of the most interesting voices in tech and design talk themselves out of writing or speaking about their work—because they don’t think they have enough experience. But you don’t have to wait for “enough“ (whatever that means). Here’s how to find what’s special about your perspective right now—wherever you are in your career.
65 |
66 | - [Advice for Technical Writing](https://css-tricks.com/advice-for-technical-writing/)
67 |
68 | > In advance of a recent podcast with the incredible technical writer and Smashing Magazine editor-in-chief Rachel Andrew, I gathered up a bunch of thoughts and references on the subject of technical writing. So many smart people have said a lot of smart things over the years that I thought I'd round up some of my favorite advice and sprinkle in my own experiences, as someone who has also done his fair share of technical writing and editing.
69 |
70 | - [Avoid the Word "Just"](https://bradfrost.com/blog/post/just/)
71 |
72 | > “Just” makes me feel like an idiot. “Just” presumes I come from a specific background, studied certain courses in university, am fluent in certain technologies, and have read all the right books, articles, and resources. “Just” is a dangerous word.
73 |
74 | - [Words To Avoid in Educational Writing](https://css-tricks.com/words-avoid-educational-writing/)
75 |
76 | > I'm no English major, but as a writer and consumer of loads of educational (mostly tech) writing, I've come to notice a number of words and phrases that come up fairly often and don't add anything to the writing. In fact, they might detract from it.
77 |
78 | > Obviously; Basically; Simply; Of course; Clearly; Just; Everyone knows; However; So; Easy;
79 |
80 | - [Plain Language Is for Everyone, Even Experts](https://www.nngroup.com/articles/plain-language-experts/)
81 |
82 | > Professionals want clear, concise information devoid of unnecessary jargon or complex terms. Plain language benefits both consumers and organizations.
83 |
84 | - [Keep Code Samples Short & Relevant](https://twitter.com/sarah_edo/status/1106631555693187073)
85 |
86 | > When writing technical blog posts, please take care that the code samples in the article aren't long. In my opinion, the post shouldn't be the full repo. Highlight the specific parts of interest, and peel away boilerplate so people can read less and learn more. Then, if needed, link to a more complete code example on [CodePen](https://codepen.io/), [JSBin](https://jsbin.com/), or something similar.
87 |
88 | - [Write a Hulk Summary](https://chriscoyier.net/2020/01/23/the-hulk-summary/)
89 |
90 | > Channel your inner Hulk voice and use it to describe whatever you need to get writing on. Hammer down that shift key (caps lock is a cop-out) and type max 4 words for each bullet to capture the core sentiment of what you’re arguing.
91 |
92 | > WRITING IS HARD; YOU THINK TOO MUCH! WE HAVE A SOLUTION; THE HULK SUMMARY!
93 |
--------------------------------------------------------------------------------
/blog/patterns.md:
--------------------------------------------------------------------------------
1 | # WordPress Shortcodes & Classes
2 |
3 | In addition to [Markdown](https://en.support.wordpress.com/markdown-quick-reference/), we have a small collection of useful shortcodes and classes to apply design patterns:
4 |
5 | Note that you'll need to disable the visual editor to use Markdown. Click on your name in the top right, and then check the "Disable the visual editor when writing" option.
6 |
7 | ## Box Shortcode
8 |
9 |
10 |
11 | The Box shortcode will create a [Post Intro](https://cloudfour-patterns.netlify.com/patterns/combos/blog.html#post-intro). It will strip any line breaks from the text.
12 |
13 | ```html
14 | [c4box]
15 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
16 | [/c4box]
17 | ```
18 |
19 | #### Grow Modifier
20 |
21 |
22 |
23 | The Grow modifier will add a [`u-textGrowX` class](https://cloudfour-patterns.netlify.com/patterns/utilities.html#text) using whatever size you pass in.
24 |
25 | ```html
26 | [c4box grow=2]
27 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
28 | [/c4box]
29 | ```
30 |
31 | You can use `grow=0` to keep the text the same size as the rest of the post, which is useful for a sort of alert box.
32 |
33 | ## Footnotes
34 |
35 |
36 |
37 | This is actually a feature of WordPress's version of [Markdown Extra](https://en.support.wordpress.com/markdown-quick-reference/).
38 |
39 | ```md
40 | I have more [^1] to say up here.
41 |
42 | (other post content)
43 |
44 | [^1]: To say down here.
45 | ```
46 |
47 | Footnotes marked up this way will be added to the bottom of the post with a link back to the original reference.
48 |
49 | ## Figure Shortcode
50 |
51 |
52 |
53 | The Figure shortcode will create a [Figure](https://cloudfour-patterns.netlify.com/patterns/components/figure.html), with an optional caption and class.
54 |
55 | ```html
56 | [c4figure caption="Our offline notification banner." class="example"]
57 |
58 | [/c4figure]
59 | ```
60 |
61 | Note the optional use of the `u-borderSm` utility class to add a light border to the image. Images with a white background may benefit from a border.
62 |
63 | ## Code Samples
64 |
65 | The WordPress Markdown editor understands both inline code using backticks — `` `code` `` — and "fenced" code blocks, using triple backticks:
66 |
67 | ````markdown
68 | ```css
69 | a {
70 | color: red;
71 | }
72 | ```
73 | ````
74 |
75 | Note that you can trigger syntax highlighting by indicating what type of code you're writing: `` ```css ``, `` ```html ``, and `` ```js ``, for example.
76 |
77 | #### Combining with Figure
78 |
79 | You can also wrap your code sample in a `c4figure` to add a caption, but because Markdown doesn't work inside WordPress shortcodes, you'll need to add the `pre` and `code` elements by hand, like so:
80 |
81 | ```html
82 | [c4figure caption="testing"]
83 |
94 |
95 | The FlexEmbed shortcode create a [Flex Embed](https://cloudfour-patterns.netlify.com/patterns/components/flex-embed.html), used to make an embed resize responsively while retaining its aspect ratio..
96 |
97 | ```html
98 | [c4flexembed]
99 |
100 | [/c4flexembed]
101 | ```
102 |
103 | #### Ratio Modifier
104 |
105 | You can manually choose the aspect ratio of the embed by setting the `ratio` attribute to either `1by1`, `2by1`, `3by1`, or `4by3`. You don't need to specify `16by9`, as that's the default.
106 |
107 | ```html
108 | [c4flexembed ratio="1by1"]
109 |
110 | [/c4flexembed]
111 | ```
112 |
113 | #### No Wrap Modifier
114 |
115 | Passing the `nowrap` modifier will prevent the embedded content from being wrapped in `
…
`. It's useful if you're manually adding the class to your embed.
116 |
117 | ```html
118 | [c4flexembed nowrap=true]
119 |
120 | [/c4flexembed]
121 | ```
122 |
123 | #### Combining with Figure
124 |
125 |
126 |
127 | You can use `c4flexembed` inside `c4figure` to add a caption to your embedded content.
128 |
129 | ```html
130 | [c4figure caption="Val Head's animation talk from Responsive Field Day"]
131 | [c4flexembed]
132 |
133 | [/c4flexembed]
134 | [/c4figure]
135 | ```
136 |
137 | ## Image Alignment
138 |
139 | ### Featured Image
140 |
141 |
142 |
143 | A featured image is pulled outside the content column, but isn't quite full-bleed. We accomplish this using [`u-pullSidesX` utility classes](https://cloudfour-patterns.netlify.com/patterns/utilities.html#space).
144 |
145 | ```html
146 |
147 | [c4figure]
148 |
149 | [/c4figure]
150 |
151 | ```
152 |
153 | Here, the combination of `u-pullSides1 u-md-pullSides6` will pull the image just outside the content container on small screens, and quite a bit more on medium and larger screens.
154 |
155 | ### Full-Bleed Image
156 |
157 |
158 |
159 | If you have an image you really want to showcase, try using the `u-release` class to make it full-bleed. Be aware this works best with images that are much wider than they are tall, otherwise users with very wide browsers may find the image fills the entire screen.
160 |
161 | ```html
162 |
163 | [c4figure caption="My book was conference SWAG! It was handed out along with t-shirts and water bottles as attendees entered the conference."]
164 |
165 | [/c4figure]
166 |
172 |
173 | Use a combination of [sizing utility classes](https://cloudfour-patterns.netlify.com/patterns/utilities.html#size) and [layout utility classes](https://cloudfour-patterns.netlify.com/patterns/utilities.html#layout) to scale and image and float it left or right.
174 |
175 | ```html
176 |
177 | [c4figure]
178 |
179 | [/c4figure]
180 |
181 | ```
182 |
183 | Here, `u-sm-size1of2` will keep the image sized to 50% of the content column, `u-sm-floatRight` will float the image to the right on small screens and larger (but not very small screens). `u-sm-spaceLeft1` ensures there's margin on the image so text doesn't run up against it, and `u-md-pullRight6` will pull the floated image slightly outside the content container on medium and larger screens.
184 |
--------------------------------------------------------------------------------
/coding/README.md:
--------------------------------------------------------------------------------
1 | ## Editors
2 |
3 | We enforce consistency in editor defaults using an **[`.editorconfig`](http://editorconfig.org/)**. The contents of our preferred editorconfig settings are:
4 |
5 | ```
6 | root = true
7 |
8 | [*]
9 | indent_style = tab
10 | indent_size = 2
11 | charset = utf-8
12 | trim_trailing_whitespace = true
13 | insert_final_newline = true
14 |
15 | [*.md]
16 | trim_trailing_whitespace = false
17 |
18 | # YAML files cannot have tabs
19 | # @see https://yaml.org/faq.html
20 | [*.yml]
21 | indent_style = space
22 | ```
23 |
24 | ### Enforcing editor defaults
25 |
26 | Automated enforcement of `.editorconfig` is enabled for you by default in boxen if you use Atom or Sublime Text.
27 |
28 | Everyone (unless you're an exception, and you'll know if that is the case) has an available `.editorconfig` in their user directory for consumption by editors.
29 |
30 | If you use a different editor, check to see if your editor has support for, or a package/plugin that supports, editorconfig and install/enable it.
31 |
32 | It is known that BBEdit, for some inexplicable reason, does not support editorconfig. It's probably possible to replicate the editorconfig settings by adjusting preferences. Shrug.
33 |
--------------------------------------------------------------------------------
/css/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [ARIA Role, State, and Property Quick Reference]: https://www.w3.org/TR/html-aria/#aria-table
4 | [About HTML Semantics and Front-end Architecture]: http://nicolasgallagher.com/about-html-semantics-front-end-architecture
5 | [Atom]: http://atom.io
6 | [Atomic CSS and Lobotomized Owls]: http://alistapart.com/article/axiomatic-css-and-lobotomized-owls
7 | [Autoprefixer]: https://github.com/postcss/autoprefixer
8 | [CSS Dig]: https://css-tricks.com/starting-a-refactor-with-css-dig/
9 | [CSS Guidelines: Architectural Principles]: http://cssguidelin.es/#architectural-principles
10 | [CSS Guidelines: JavaScript Hooks]: http://cssguidelin.es/#javascript-hooks
11 | [CSS Guidelines]: http://cssguidelin.es
12 | [CSS Property Order]: http://markdotto.com/2011/11/29/css-property-order/
13 | [CSS Reset]: http://meyerweb.com/eric/tools/css/reset/
14 | [CSScomb config]: http://
15 | [CSScomb]: http://csscomb.com
16 | [Code Guide by @mdo]: http://codeguide.co/#css
17 | [KSS]: https://github.com/kss-node/kss-node
18 | [Modular CSS BEM/OOCSS Naming]: http://benfrain.com/modular-css-bem-oocss-naming/
19 | [Naming CSS Stuff Is Really Hard]:http://seesparkbox.com/foundry/naming_css_stuff_is_really_hard
20 | [normalize.css]: http://necolas.github.io/normalize.css/
21 | [Outside In]: http://webdesign.tutsplus.com/articles/outside-in-ordering-css-properties-by-importance--cms-21685
22 | [PostCSS]: https://github.com/postcss/postcss
23 | [Rework]: https://github.com/reworkcss/rework
24 | [SUIT CSS Linter]: https://github.com/necolas/postcss-bem-linter
25 | [SUIT CSS Naming Conventions]: https://github.com/suitcss/suit/blob/master/doc/naming-conventions.md
26 | [SUIT CSS Utils]: https://github.com/suitcss/utils
27 | [Sass Guidelines: The 7-1 Pattern]: http://sass-guidelin.es/#the-7-1-pattern
28 | [stylelint]: https://stylelint.io/
29 | [stylefmt]: https://github.com/morishitter/stylefmt
30 | [Sublime Text]: http://sublimetext.com
31 | [The CSS Specificity Graph]: http://csswizardry.com/2014/10/the-specificity-graph/
32 |
33 | # CSS Guide
34 |
35 | Clean, consistent and understandable CSS is paramount to a successful project. It sets the tone, both visually and architecturally, for the entire front-end. These are our collected (and evolving) best practices for writing styles with some _style_. 😎
36 |
37 | - [Organization](#organization)
38 | - [Directory Structure](#directory-structure)
39 | - [Base Styles](#base-styles)
40 | - [Components](#components)
41 | - [Utilities](#utilities)
42 | - [Conventions](#conventions)
43 | - [General Rules](#general-rules)
44 | - [Property Sorting](#property-sorting)
45 | - [Selectors](#selectors)
46 | - [Class Naming](#class-naming)
47 | - [Comments](#comments)
48 | - [Architecture](#architecture)
49 | - [Dryness](#dryness)
50 | - [Encapsulation](#encapsulation)
51 | - [Composition](#composition)
52 | - [Compatibility](#compatibility)
53 | - [Tools](#tools)
54 | - [Processors](#processors)
55 | - [Formatters](#formatters)
56 | - [Validators](#validators)
57 | - [Analyzers](#analyzers)
58 |
59 | ## Organization
60 |
61 | ### Directory Structure
62 |
63 | This structure is an adaptation of [Sass Guidelines: The 7-1 Pattern]. It represents the organization of different types of style sheets, and the order they should follow. Unless specific project requirements dictate otherwise, the directory structure should look _something_ like this:
64 |
65 |
82 |
83 | ### Base Styles
84 |
85 | The `base/` directory should contain foundational styles and other global dependencies. There should be few (if any) class definitions within this directory. In addition to common variables, this would also be an appropriate place to put mixins or functions if a preprocessor is in use.
86 |
87 | - Variables, mixins and functions should be organized in their own separate files.
88 |
89 | ```css
90 | /* base/variables.css */
91 |
92 | :root {
93 | --font-family-sans: popular-sans, "Helvetica Neue", sans-serif;
94 | --font-size-base: 22px;
95 | --transition-duration: 360ms;
96 | }
97 |
98 | @custom-media --width-min-md screen and (min-width: 30em);
99 | @custom-media --width-min-lg screen and (min-width: 60em);
100 | ```
101 |
102 | - Each file should only be responsible for providing base styles for a designated group of related elements.
103 |
104 | ```css
105 | /* base/scaffolding.css */
106 |
107 | * {/*...*/}
108 |
109 | html {/*...*/}
110 |
111 | body {/*...*/}
112 | ```
113 |
114 | ```css
115 | /* base/forms.css */
116 |
117 | label {/*...*/}
118 |
119 | input {/*...*/}
120 |
121 | button {/*...*/}
122 | ```
123 |
124 | ```css
125 | /* base/typography.css */
126 |
127 | h1,
128 | h2,
129 | h3 {/*...*/}
130 |
131 | pre,
132 | code {/*...*/}
133 | ```
134 |
135 | ### Components
136 |
137 | The `components/` directory should have the largest number of files, because most of the CSS should be written as small, reusable components.
138 |
139 | - Each file should contain only one component and, if possible, only class selectors with a common namespace for that component:
140 |
141 | ```css
142 | /* components/alert.css */
143 |
144 | .Alert {/*...*/}
145 |
146 | .Alert--fixed {/*...*/}
147 |
148 | .Alert-header {/*...*/}
149 |
150 | .Alert-closeButton {/*...*/}
151 | ```
152 |
153 | ```css
154 | /* components/button.css */
155 |
156 | .Button {/*...*/}
157 |
158 | .Button--large {/*...*/}
159 |
160 | .Button--small {/*...*/}
161 | ```
162 |
163 | ### Utilities
164 |
165 | The `utilities/` directory is where definitions for utility classes (or "helpers") should occur. Unlike components, there may be many of these class definitions per file. Their organization should be according to what kind of properties they affect. See [SUIT CSS Utils] for a nice example of this organization.
166 |
167 | - Each file should contain only classes prefixed with `u-` to identity them as utilities.
168 |
169 | ```css
170 | /* utilities/margin.css */
171 |
172 | .u-marginAbove {
173 | margin-top: var(--vspace) !important;
174 | }
175 |
176 | .u-marginBelow {
177 | margin-bottom: var(--vspace) !important;
178 | }
179 | ```
180 |
181 | - To ensure dominance over conflicting declarations, **utilities should come last after all other styles** in `main.css`.
182 |
183 | ```css
184 | /* main.css */
185 |
186 | @import "base";
187 | @import "components";
188 | @import "sections";
189 | @import "utils";
190 | ```
191 |
192 | [⇧ top](#css-guide)
193 |
194 |
195 | ## Conventions
196 |
197 | ### General Rules
198 |
199 | These rules were adapted from [CSS Guidelines]. This is an example of how declaration block syntax should be formatted (Sass syntax used to illustrate nesting):
200 |
201 | ```sass
202 | .Selector-1,
203 | .Selector-2 { /* 1 */
204 | @include some-mixin(); /* 2 */
205 |
206 | display: block; /* 3 */
207 | background-color: rgba(0, 0, 0, 0.1); /* 4 */
208 | background-image: url("image.png"); /* 5 */
209 | opacity: 0.8; /* 6 */
210 | padding: 0; /* 7 */
211 | transition-duration: 0.3s; /* 8 */
212 |
213 | &:hover,
214 | &:focus { /* 9 */
215 | color: green;
216 | }
217 |
218 | &.is-disabled,
219 | &[disabled] { /* 10 */
220 | pointer-events: none;
221 | }
222 |
223 | @media (min-width: 40em) { /* 11 */
224 | width: auto;
225 | }
226 |
227 | &::before { /* 12 */
228 | content: "Foo";
229 | }
230 | } /* 13 */
231 | /* 14 */
232 | ```
233 |
234 | 1. Combined selectors should be on separate lines, and the opening brace should be on the same line as the last selector.
235 | 2. Variables and preprocessor cruft should come before any properties, separated with blank line below.
236 | 3. One space should be after each colon, and each line should end with a semicolon.
237 | 4. Comma-delimited numbers inside of values with parenthesis (e.g. `rgb(0, 0, 0)`) should have spaces between them.
238 | 5. Strings within values should use double quotes.
239 | 6. Decimal values should include a leading `0`.
240 | 7. Values of zero should be unit-less.
241 | 8. Time values should be represented with the second (`s`) unit. This is easier for humans to parse, and encourages shorter values that divide evenly within an ideal 60 frames-per-second animation speed.
242 | 9. Nested pseudo class blocks should come after all property declarations.
243 | 10. Nested class or attribute blocks should come after all pseudo class blocks.
244 | 11. Nested media queries should come after all combined class or attribute blocks.
245 | 12. Nested pseudo element blocks should come after all media queries.
246 | 13. Closing braces should be on a new line.
247 | 14. A blank line should come after each declaration block.
248 |
249 | ### Order of Nested Selectors
250 |
251 | We use a standard order for nested selectors in Sass. By following this order, our code becomes more standardized and easier to understand.
252 |
253 | When in doubt, remember that the goal is to first define any **included** styles, followed by **regular** styles, followed by **modifiers**, followed by **children** (whose code would follow this same order).
254 |
255 |
256 | 1. #### Included Code
257 |
258 | 1. Local `$variables`
259 | * Local variables should really only be declared for mixins or functions. Most variables should be kept in the main variables partial, since variables in Sass are global.
260 | * However, if you have a set of variables that will only be used in a certain partial, declare them at the top of that file and prefix their names to avoid confusion in the global namespace. e.g., `$m_module_name_height`.
261 |
262 | 1. `@extend` statements
263 | * Avoid extends in favor of mixins. Extends offer no benefits over mixins, and can cause [specificity problems](http://csswizardry.com/2016/02/mixins-better-for-performance/).
264 |
265 | 1. `@include` statements
266 | * Knowing right off the bat that this class inherits another whole set of rules from elsewhere is good. Another benefit is that overriding styles for that inherited set of rules becomes much easier.
267 |
268 | 2. #### Alphabetized Regular Styles
269 | 1. Adding regular styles after the `@extend` and `@include` statements allows us to override those properties, if needed. Be sure to leave a comment if a declaration's only purpose is to override included styles.
270 |
271 | 1. Alphabetizing is helpful for a large team because it standardizes location of properties (See "Property Sorting" below).
272 |
273 | 3. #### Modifiers
274 | 1. Pseudo-classes (`:hover`), attribute selectors (`&[type="input"]`), and state classes (`&.is-active`)
275 | * These directly modify the parent selector so we declare them before other nested selectors.
276 | * Most BEM modifier classes don't need to be nested. However, some generic state class names like `is-active` that would otherwise be too non-specific to live in the global namespace, should be nested here.
277 |
278 | 1. Nested media queries
279 | * These come after regular styles, pseudo-classes, etc., so they can override them.
280 |
281 | 1. Parent modifier classes (`.parent__modifier &`)
282 | * Modifiers on parents can affect children. They should be nested like media queries.
283 |
284 | 4. #### Child Selectors
285 |
286 | 1. Pseudo-elements (`::before`)
287 | * Pseudo-elements are actually generated children, and so should be treated like any other nested selector.
288 |
289 | 2. Nested selectors
290 | * As a rule, **if a selector will work without it being nested then do not nest it.**
291 | * There shouldn’t be many nested selectors. Our naming convention means that we don’t need to nest selectors for namespacing. Before you nest a selector, consider if it would be better as a child class or modifier class.
292 | * Any nested selectors could contain their own nested pseudo-classes, pseudo-elements and media queries, following the rules above.
293 |
294 | ```sass
295 | .foo {
296 | @include font_ui(2.0); // 1.iii
297 | line-height: 1; // override font_ui line-height, 2.i
298 | width: 100%; // 2.ii
299 |
300 | &:hover { // 3.i - modifier: pseudo-class
301 | color: red;
302 | }
303 |
304 | // state classes usually have `is-` or `has-` class names that need to be nested.
305 | &.has-error { // 3.i - modifier: state class
306 | color: red;
307 | }
308 |
309 | @media only screen and (min-width: $screen_medium) { // 3.ii - modifier: media query
310 | width: 100%;
311 | }
312 |
313 | @media only screen and (min-width: $screen_large) { // 3.ii - modifier: media query
314 | width: 50%;
315 | }
316 |
317 | &::before { // 4.i - child: pseudo-element
318 | content: "!";
319 | }
320 |
321 | // this should really be a non-nested BEM child class!
322 | h2 { // 4.ii - child: nested selector
323 | font-size: 2em;
324 | }
325 | }
326 |
327 | // modifier with proper BEM name
328 | // note the nested selectors follow the same order.
329 | .foo--bar {
330 | color: red;
331 |
332 | &:hover {
333 | color: orange;
334 | }
335 |
336 | @media only screen and (min-width: $screen_large) {
337 | display: none;
338 | }
339 | }
340 |
341 |
342 | // child element with proper BEM name
343 | .foo__icon {
344 | width: 1em;
345 |
346 | // nested modifier makes it easier to understand
347 | .foo--bar & {
348 | width: 2em;
349 | }
350 | }
351 | ```
352 |
353 | ### Property Sorting
354 |
355 | Until recently, we followed Guy Routledge's [Outside In] method of property sorting. Over time, we discovered most property sorting methodologies require maintenance as new properties (for example, `flex-*` or `grid-*`) are introduced. This makes them inherently fragile and difficult to enforce.
356 |
357 | We now recommend properties are sorted alphabetically. This technique will scale to accommodate any new properties, and requires no learning curve for new project contributors.
358 |
359 | * You can quickly alphabetize declarations in Sublime Text by selecting several lines of code and pressing F5.
360 | * You can quickly alphabetize declarations in VS Code by selecting several lines of code and using the "Sort Lines Ascending" command. This has no keyboard shortcut by default, so you can either use the command pallete (CMD+SHIFT+P) or assign a keyboard shortcut.
361 |
362 | ```css
363 | /* Do */
364 |
365 | selector {
366 | display: flex;
367 | font-size: 2em;
368 | left: 0;
369 | position: absolute;
370 | top: 0;
371 | }
372 | ```
373 |
374 | ```css
375 | /* Don't */
376 |
377 | selector {
378 | position: absolute;
379 | top: 0;
380 | left: 0;
381 | display: flex;
382 | font-size: 2em;
383 | }
384 | ```
385 |
386 | It is recommended to use tools like [stylelint] to enforce these sorts of rules, which can be combined with the `--fix` option or a complementary tool like [stylefmt] to organize CSS properties from text editors like [Atom] and [Sublime Text].
387 |
388 | ### Selectors
389 |
390 | - ID selectors should be avoided
391 |
392 | ```css
393 | /* Don't */
394 |
395 | #some-id {}
396 | ```
397 |
398 | ```css
399 | /* Don't even */
400 |
401 | element#some-id {}
402 | ```
403 |
404 | - Element selectors should be avoided outside of defining base styles
405 |
406 | ```css
407 | /* Don't */
408 |
409 | .Component ul {}
410 | ```
411 |
412 | ```css
413 | /* Don't */
414 |
415 | .Component > span {}
416 | ```
417 |
418 | ```css
419 | /* Don't */
420 |
421 | li.Component-item {}
422 | ```
423 |
424 | - Nesting should be avoided unless the resulting specificity is actually needed
425 |
426 | ```css
427 | /* Do */
428 |
429 | .Component {}
430 |
431 | .Component-element {}
432 | ```
433 |
434 | ```css
435 | /* Don't */
436 |
437 | .Component {}
438 |
439 | .Component .Component-element {}
440 | ```
441 |
442 | **Note:** It is also acceptable to "nest" pseudo classes and pseudo elements when using a preprocessor, since doing this has no unintentional effect on specificity.
443 |
444 | - Nested selectors may only be two levels deep and must consist of a modifier class followed by an element class
445 |
446 | ```css
447 | .Component--modifier .Component-element {}
448 | ```
449 |
450 | - Unrelated selectors should not be combined
451 |
452 | ```css
453 | /* Do */
454 |
455 | h1,
456 | h2,
457 | h3 {
458 | font-weight: bold;
459 | letter-spacing: -0.1em;
460 | }
461 | ```
462 |
463 | ```css
464 | /* Don't */
465 |
466 | .Component-header,
467 | .OtherComponent-header,
468 | .AnotherComponent--extended {
469 | margin-top: 0;
470 | }
471 | ```
472 |
473 | **Note:** If using a preprocessor like Sass, the `@extend` feature should be used with great care to avoid the unintentional combining of unrelated selectors.
474 |
475 | ### Class Naming
476 |
477 | Naming stuff can be hilariously difficult. To minimize future confusion, try to pick names that are less likely to change (or become inaccurate). For example, a component name of `.FormGroup` might be better than `.RegistrationShipping`, since it describes a _function_ rather than a _context_. See [Naming CSS Stuff Is Really Hard] for more examples.
478 |
479 | The following conventions were adapted from the [SUIT CSS Naming Conventions].
480 |
481 | #### Utility Classes
482 |
483 | Syntax: `u-[sm|md|lg-]`
484 |
485 | ```css
486 | .u-floatLeft {
487 | float: left !important;
488 | }
489 |
490 | @media (--sm) {
491 | .u-sm-floatLeft {
492 | float: left !important;
493 | }
494 | }
495 | ```
496 |
497 | #### Component Classes
498 |
499 | Syntax: `[--modifierName|-descendentName`
500 |
501 | ```css
502 | /* Component Name */
503 | .Alert {}
504 |
505 | /* Modifier */
506 | .Alert--dismissable {}
507 |
508 | /* Descendent */
509 | .Alert-closeButton {}
510 |
511 | /* Modifying descendants */
512 | .Alert--dismissable .Alert-closeButton {}
513 | ```
514 |
515 | Avoid nesting descendents:
516 |
517 | ```css
518 | /* Do */
519 |
520 | .Nav-subnavButton {}
521 |
522 | /* Don't */
523 |
524 | .Nav-subnav-button {}
525 | ```
526 |
527 | If you find yourself wanting complex parent-child relationships within a single component, you may benefit from breaking it into into multiple independent components:
528 |
529 | ```css
530 | .Nav {}
531 |
532 | .Subnav {}
533 | ```
534 |
535 | #### States
536 |
537 | Syntax: `.is-stateOfComponent`
538 |
539 | State classes should reflect changes to a component's state. As such, it's important to resist the temptation to apply direct styles to these classes. Scoping states to associated component classes insures the use of consistent cross-component terminology.
540 |
541 | ```css
542 | /* Component Name */
543 | .Tweet {}
544 |
545 | /* State of component */
546 | .Tweet.is-expanded {}
547 | ```
548 |
549 | It's also acceptable (and in some cases preferred) to manage state via built-in browser properties:
550 |
551 | ```css
552 | .Toggle:checked {}
553 |
554 | .Input:disabled {}
555 |
556 | .Tweet[aria-expanded="true"] {}
557 | ```
558 |
559 | #### Micro-semantics
560 |
561 | When deciding how to construct complex class names with multiple delimited pieces, look at existing HTML specifications for inspiration before deciding on something arbitrary.
562 |
563 | The [ARIA Role, State, and Property Quick Reference] is a good resource for common element and state names.
564 |
565 | ```css
566 | /* Elements */
567 |
568 | .Component-body {}
569 | .Component-header {}
570 | .Component-button {}
571 | .Component-dialog {}
572 | .Component-img {}
573 | ```
574 |
575 | ```css
576 | /* Modifiers */
577 |
578 | .Component--labelled {}
579 | .Component--hasPopop {}
580 | ```
581 |
582 | ```css
583 | /* States */
584 |
585 | .Component.is-busy {}
586 | .Component.is-expanded {}
587 | .Component.is-checked {}
588 | .Component.is-selected {}
589 | ```
590 |
591 | #### JavaScript Hooks
592 |
593 | See [CSS Guidelines: JavaScript Hooks]
594 |
595 | ### Comments
596 |
597 | Comments are a good idea. There is no standardized CSS documentation tool ([KSS] for example) currently in use. For comments that explain declarations, this formatting is nice:
598 |
599 | From https://github.com/suitcss/components-arrange/blob/master/lib/arrange.css
600 |
601 | ```css
602 | /**
603 | * 1. Protect against the component expanding beyond the confines of its
604 | * container if properties affecting the box-model are applied to the
605 | * component. Mainly necessary because of (5).
606 | * 2. Rely on table layout.
607 | * 3. Zero out the default spacing that might be on an element (e.g., `ul`).
608 | * 4. Make sure the component fills at least the full width of its parent.
609 | * 5. Reset the table-layout algorithm in case a component is nested.
610 | */
611 |
612 | .Arrange {
613 | box-sizing: border-box; /* 1 */
614 | display: table; /* 2 */
615 | margin: 0; /* 3 */
616 | min-width: 100%; /* 4 */
617 | padding: 0; /* 3 */
618 | table-layout: auto; /* 5 */
619 | }
620 | ```
621 |
622 | Avoid simply restating what the property already tells us. Try to provide useful clarification of _why_ a rule was chosen.
623 |
624 | ```css
625 | /* Don't */
626 |
627 | /**
628 | * 1. Use relative positioning.
629 | */
630 |
631 | .Nav {
632 | position: relative; /* 1 */
633 | }
634 |
635 | /* Do */
636 |
637 | /**
638 | * 1. Allow child elements like the logo to position themselves relative
639 | to this container.
640 | */
641 |
642 | .Nav {
643 | position: relative; /* 1 */
644 | }
645 | ```
646 |
647 | [⇧ top](#css-guide)
648 |
649 |
650 | ## Architecture
651 |
652 | See [CSS Guidelines: Architectural Principles]
653 |
654 | ### Dryness
655 |
656 | Use the following properties with care. They should occur in reusable utilities most of the time, and not repeated across a wide variety of components.
657 |
658 | - `margin`
659 | - `float`
660 | - `width`
661 | - `height`
662 | - `font-*`
663 | - `line-height`
664 | - `text-align`
665 | - `white-space`
666 |
667 | ### Encapsulation
668 |
669 | When writing base styles for a component, assume that the component is unaware of everything outside of its box. Add styles that depend on surrounding elements with care (or instead use more utility classes in your HTML.)
670 |
671 | ```css
672 | /* Do */
673 |
674 | .Component {
675 | display: block;
676 | }
677 |
678 | .Component--withMargin {
679 | margin-top: 1em;
680 | }
681 |
682 | .Component--size1of2 {
683 | width: 50%;
684 | }
685 | ```
686 |
687 | ```css
688 | /* Don't */
689 |
690 | .Component {
691 | margin-top: 1em;
692 | display: block;
693 | width: 50%;
694 | }
695 | ```
696 |
697 | ### Composition
698 |
699 | When combining components for specific overrides, do this in a context-specific style sheet:
700 |
701 | ```css
702 | /* sections/search.css */
703 |
704 | .Section--search .Button {/*...*/}
705 | ```
706 |
707 | If this combination reoccurs, consider creating a new component to abstract the needed pieces:
708 |
709 | ```css
710 | /* components/searchbar.css */
711 |
712 | .SearchBar {/*...*/}
713 |
714 | .SearchBar-button {/*...*/}
715 | ```
716 |
717 | ### Compatibility
718 |
719 | Vendor prefixes or other non-standard fallbacks make CSS difficult to read and maintain. Even mixins require documentation and maintenance. [Autoprefixer] will handle prefixes and other fallbacks based on your project's actual support requirements. This allows us to write styles in a standard and predictable way:
720 |
721 | ```scss
722 | /* Don't */
723 | .Component {
724 | -webkit-transform: translateX(-50%);
725 | -ms-transform: translateX(-50%);
726 | transform: translateX(-50%);
727 | }
728 |
729 | /* Don't */
730 | .Component {
731 | @include translateX(-50%);
732 | }
733 |
734 | /* Do */
735 | .Component {
736 | transform: translateX(50%);
737 | }
738 | ```
739 |
740 | [⇧ top](#css-guide)
741 |
742 |
743 | ## Tools
744 |
745 | ### Processors
746 |
747 | - **[PostCSS]**
748 |
749 | ### Validators
750 |
751 | - **[stylelint]** With this plugin, you can check the validity of stylesheets against a set of project-specific conventions. The plugin will throw an error if it finds CSS that violates these rules.
752 |
753 | ### Formatters
754 |
755 | - **[stylefmt]** Works alongside stylelint to help format your code.
756 |
757 | ### Analyzers
758 |
759 | - **[The CSS Specificity Graph]** A very simple model for diagrammatically assessing the overall health of your codebase in terms of specificity—a way of looking at an entire project’s CSS and highlighting any potentially troublesome areas of higher-than-ideal specificity.
760 | - **[CSS Dig]** A Chrome extension that summarizes selector and propery usage for any given page. Particularly useful for identifying areas of needless repetition (see [Dryness](#dryness)).
761 |
762 | [⇧ top](#css-guide)
763 |
764 |
--------------------------------------------------------------------------------
/design/deliverables/README.md:
--------------------------------------------------------------------------------
1 | # Design Deliverables
2 |
3 | Our process retires or streamlines many traditional design steps to promote transparency between internal and external teams while also decreasing the distance between what we design and what the user actually experiences.
4 |
5 | The exact deliverables differ per project, but may include some or all of the following…
6 |
7 | - TODO: Prioritization Exercises
8 | - TODO: Personas
9 | - [Mood Boards](#mood-boards)
10 | - [Element Collages](#element-collages)
11 | - TODO: Collaborative Sketches
12 | - TODO: Wireframes
13 | - TODO: Prototypes
14 |
15 | ## Mood Boards
16 |
17 | A collage of images, textures, typography, colors or other materials, intended to evoke or visually summarize a particular style or concept.
18 |
19 | 
20 |
21 | Mood boards work best as part of the discovery phase of a project when brand characteristics are unknown, in flux or poorly applied to the web. They help internal and external teams get on the same page, establishing a shared frame of reference before we get in the weeds of more time-consuming, wholly original design tasks.
22 |
23 | - **After:** Prioritization exercises, personas
24 | - **Before:** Element collages
25 | - **Timeframe:** 1–3 days per revision
26 | - **Revisions:** Typically 1–3
27 | - **Collaborators:** 1–2 designers + anyone who'd like to contribute!
28 |
29 | ### Tips
30 |
31 | - Include materials you _know_ to be relevant as a starting point. This can include text notes summarizing priorities or characteristics, existing brand materials, or photographs of a physical location.
32 | - Share mood boards while they're still in progress. This promotes understanding of the board's malleable nature and the process for creating it.
33 | - Whenever possible, invite the client to collaborate on the mood board, either directly or by contributing comments/feedback.
34 | - Aside from color/gradient swatches, cropping or lighting adjustments to photographic imagery, avoid creating original work for mood boards. This takes more time, removes discussion from the design process and encourages feedback on specific design decisions over the board's _overall_ appropriateness.
35 | - Avoid presenting competing mood boards. While it's fine for a mood board to have complimentary sections to gauge interest in differing perspectives ("cool + modern," "bright + friendly"), simplifying a mood board review to "A versus B" can discourage discussion of the elements therein.
36 |
37 | ### Tools
38 |
39 | Mood boards are traditionally assembled in-person by cutting out pieces of magazines or other printed materials, then collaging them on matte board or some other surface. At Cloud Four we tend to use digital tools instead. This helps us collaborate more seamlessly with remote teams while also referencing more relevant digital imagery.
40 |
41 | - [InVision Boards](https://www.invisionapp.com/blog/boards-share-design-inspiration-assets/)
42 | - [Niice](https://niice.co/)
43 |
44 | ### Further Reading
45 |
46 | - [Cloud Four: Mood Boards (Neither Bored Nor Moody)](https://cloudfour.com/thinks/mood-boards/)
47 |
48 | ## Element Collages
49 |
50 | A collage of original but disparate design elements meant to demonstrate ideas without committing to a particular layout. As originator [Dan Mall](http://v3.danielmall.com/articles/rif-element-collages/) put it:
51 |
52 | > A full comp often requires ideas to be fully realized. An element collage allows me to document a thought at any state of realization and move on to the next.
53 |
54 | 
55 |
56 | At the beginning of a project, element collages bridge the gap between explorational exercises like mood boards and more fleshed-out deliverables like in-browser mockups and prototypes. They're an ideal deliverable for figuring out foundational colors, typography, line weights and other design elements that can carry into the foundational CSS for in-browser mockups.
57 |
58 | Throughout a project, they may be used more informally to explore ideas and inform prototypes.
59 |
60 | - **After:** Mood boards
61 | - **Before:** Prototypes
62 | - **Timeframe:** 1–3 days per revision
63 | - **Revisions:** Typically 2–4
64 | - **Collaborators:** Ideally 2 or more designers work in parallel to create complimentary collages, eventually unifying their approach prior to prototyping. While prototyping, they can be created as simple one-off explorations (as needed).
65 |
66 | ### Tips
67 |
68 | - Don't try to design every possible pattern in your collage. Instead, focus on elements you have an instinct to explore that could inform future patterns.
69 | - Avoid composing elements of your collage in a manner that suggests a complete "page," which will disrupt the viewer's ability to critique the elements therein. If you find yourself unable to prevent this, it may be time to split your collage into separate images or artboards.
70 | - If you have an idea for animation or interaction, don't be afraid to use [blur](http://v3.danielmall.com/articles/rif-element-collages/rif-element-collage-sample.png), [gesture overlays](https://www.lukew.com/ff/entry.asp?1071) or other visual techniques to communicate that intent in an efficient way.
71 | - If working in parallel, freely steal borrow from your collaborators. Let every team member's work inform and strengthen the overall vision. Share your source files, messy layers and all.
72 | - If multiple designers end up pursuing very similar design directions, branch off by applying that direction to different elements.
73 |
74 | ### Tools
75 |
76 | We love designing in-browser, but it's usually a better idea to do looser explorations in a more free-form tool. Not having to worry about markup, box models or even responsive design considerations at this stage helps maintain a sense of play and inventiveness in our work. This helps us avoid designing [the same interface over and over](http://www.novolume.co.uk/blog/all-websites-look-the-same/).
77 |
78 | - [Sketch](https://www.sketchapp.com/)
79 | - [Adobe XD](http://www.adobe.com/products/experience-design.html)
80 | - [Adobe Photoshop](http://www.adobe.com/products/photoshop.html)
81 | - [Figma](https://www.figma.com/)
82 |
83 | ### Further Reading
84 |
85 | - [Dan Mall: Element Collages](http://v3.danielmall.com/articles/rif-element-collages/)
86 | - [Cloud Four: Element Collages… are FUN!](https://cloudfour.com/thinks/element-collages-are-fun/)
87 |
--------------------------------------------------------------------------------
/design/deliverables/images/elementcollage-cloudfour.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudfour/guides/6ed34d0b282c3483e013aee776782c6ae064c8f8/design/deliverables/images/elementcollage-cloudfour.jpg
--------------------------------------------------------------------------------
/design/deliverables/images/moodboard-cloudfour.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudfour/guides/6ed34d0b282c3483e013aee776782c6ae064c8f8/design/deliverables/images/moodboard-cloudfour.png
--------------------------------------------------------------------------------
/git/README.md:
--------------------------------------------------------------------------------
1 | [pull request]: https://help.github.com/articles/using-pull-requests
2 | [pull request template]: https://help.github.com/articles/creating-a-pull-request-template-for-your-repository/
3 | [name your feature branches by convention]: https://docs.microsoft.com/en-us/vsts/git/concepts/git-branching-guidance?view=vsts#name-your-feature-branches-by-convention
4 |
5 | Git Protocol
6 | ============
7 |
8 | A guide for programming within version control.
9 |
10 | ## Table of Contents
11 |
12 | - [General Guidelines](#general-guidelines)
13 | - [Writing a Feature](#writing-a-feature)
14 | - [Reviewing Code](#reviewing-code)
15 | - [Merging in General](#merging-in-general)
16 | - [Pull Request Template](#pull-request-template)
17 | - [Write Useful Commit Messages](#write-useful-commit-messages)
18 |
19 |
20 | General Guidelines
21 | ------------------
22 |
23 | * Avoid including files that are specific to your own environment.
24 | * Avoid committing directly to `main`.
25 | * Perform all work in a feature branch.
26 | * Rebase frequently to incorporate upstream changes.
27 | * Use a [pull request] for code reviews.
28 | * Delete your local and remote branches after merging.
29 |
30 | Writing a Feature
31 | -----------------
32 |
33 | ### Create a local feature branch based off main
34 |
35 | ```
36 | git checkout main
37 | git pull
38 | git checkout -b
39 | ```
40 |
41 | Prefix the branch name with something meaningful, for example:
42 |
43 | - `users/username/description`
44 | - `users/username/workitem`
45 | - `feature/feature-name`
46 | - `feature/feature-area/feature-name`
47 | - `bugfix/description`
48 | - `hotfix/description`
49 | - `cleanup/description`
50 | - `chore/description`
51 |
52 | When you [name your feature branches by convention] using slashes,
53 | it provides a much nicer organization when viewing as directories
54 | as well as within any Git GUI apps.
55 |
56 | ### Rebase frequently to incorporate upstream changes
57 |
58 | ```
59 | git fetch origin
60 | git rebase origin/main
61 | ```
62 |
63 | Resolve conflicts. When feature is in a good state, stage the changes
64 |
65 | ```
66 | git add --all
67 | ```
68 |
69 | ### Commit your changes
70 |
71 | ```
72 | git status
73 | git commit --verbose
74 | ```
75 |
76 | Be sure to [write a good commit message](#write-useful-commit-messages).
77 |
78 | If you've created more than one commit, use a rebase to squash them into
79 | cohesive commits with good messages:
80 |
81 | ```
82 | git rebase -i origin/main
83 | ```
84 |
85 | ### Push your branch
86 |
87 | ```
88 | git push origin
89 | ```
90 |
91 | Submit a [pull request]. Ask for a code review.
92 |
93 | Reviewing Code
94 | --------------
95 |
96 | ### Fellow team members review the pull request
97 |
98 | Your team members will follow code review guidelines to avoid miscommunication.
99 | They make comments and ask questions directly on lines of code.
100 | When satisfied, they'll approve your pull request and leave a comment:
101 |
102 | > This is some excellent work, Ross. :thumbsup:
103 |
104 | Merging in General
105 | ------------------
106 |
107 | Once your PR has been approved, you are responsible for merging it.
108 |
109 | ### Rebasing
110 |
111 | To avoid a messy history, please rebase and squash low-value commits
112 | like "Fix whitespace" into one or a small number of valuable commit(s).
113 | Edit commit messages to reveal intent. Run tests.
114 |
115 | ```
116 | git fetch origin
117 | git rebase -i origin/main
118 | ```
119 |
120 | ### Force-Pushing
121 |
122 | This allows GitHub to automatically close your pull
123 | request and mark it as merged when your commit(s) are pushed to `main`. It also
124 | makes it possible to find the pull request that brought in your changes.
125 |
126 | ```
127 | git push --force origin
128 | ```
129 |
130 | ### The Big Green Button Method
131 |
132 | Force-pushing may not always be appropriate for every project, depending on
133 | other factors like hooks or continuous integration. Pull Requests may also be
134 | merged into `main` (or whatever their target branch is) by simply
135 | clicking the green "Merge Branch" button on the GitHub Pull Request page.
136 |
137 | Note that GitHub offers three merge options: a merge commit, rebase and merge,
138 | and squash and merge. All are good for different situations. For example,
139 | merge commits are good for merging feature branches with many developers or
140 | that other feature branches depend on.
141 |
142 | For short-lived, single-developer feature branches, we favor squashing to
143 | preserve a clean and easy-to-follow history.
144 |
145 | - [How and Why to Squash Merge your Pull Request](https://cloudfour.com/thinks/squashing-your-pull-requests/)
146 |
147 | ### Once merged, delete your branch
148 |
149 | Delete the remote branch.
150 |
151 | ```
152 | git push origin --delete
153 | ```
154 |
155 | Delete your local feature branch.
156 |
157 | ```
158 | git branch --delete
159 | ```
160 |
161 | ## Pull Request Template
162 |
163 | Please add a [Pull Request Template] to your repo,
164 | to ensure that all pull requests follow our guide:
165 |
166 | See our [Standard Pull Request Template](./pull_request_template.md) in this directory.
167 |
168 | ## Write Useful Commit Messages
169 |
170 | Please ensure that you follow commit message best practices:
171 |
172 | 1. Separate subject from body with a blank line
173 | 1. Limit the subject line to 50 characters
174 | 1. Capitalize the first word of the subject line
175 | 1. Do not end the subject line with a period
176 | 1. Use the imperative mood in the subject line
177 | (e.g. "Fix the bug" not "Fixed the bug")
178 | 1. Wrap the body at 72 characters
179 | 1. Use the body to explain what and why vs. how
180 |
181 | For example:
182 |
183 | ```
184 | Present-tense summary under 50 characters
185 |
186 | * More information about commit (under 72 characters).
187 | * More information about commit (under 72 characters).
188 |
189 | http://project.management-system.com/ticket/123
190 | ```
191 |
192 | ### Commit Message Best Practices
193 | - [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
194 | - [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/)
195 | - [Commit Messages Guide](https://github.com/RomuloOliveira/commit-messages-guide)
196 |
197 | ### Commit Message Template
198 |
199 | See our [Standard Commit Message Template](./commit_template.txt) in this directory.
200 |
201 | To use the template, save it to your local machines and add it to your `.gitconfig`:
202 |
203 | ```
204 | git config --global commit.template <.git-commit-template.txt file path>
205 | ```
206 |
207 | For example, if you saved it to your home folder, try:
208 |
209 | ```
210 | git config --global commit.template ~/.git-commit-template.txt
211 | ```
212 |
--------------------------------------------------------------------------------
/git/commit_template.txt:
--------------------------------------------------------------------------------
1 | # : Short subject line
2 | # |<---- Using a Maximum Of 50 Characters ---->|
3 |
4 |
5 | # Explain why this change is being made
6 | # |<---- Try To Limit Each Line to a Maximum Of 72 Characters ---->|
7 |
8 | # Provide links or keys to any relevant tickets, articles or other resources
9 | # e.g.: Fixes #23
10 |
11 | # --- COMMIT END ---
12 | # Type can be
13 | # feat (new feature)
14 | # fix (bug fix)
15 | # refactor (refactoring production code)
16 | # style (formatting, missing semi colons, etc; no code change)
17 | # docs (changes to documentation)
18 | # test (adding or refactoring tests; no production code change)
19 | # chore (updating grunt tasks etc; no production code change)
20 | # --------------------
21 | # Remember to
22 | # Capitalize the subject line
23 | # Use the imperative mood in the subject line
24 | # Do not end the subject line with a period
25 | # Separate subject from body with a blank line
26 | # Use the body to explain what and why vs. how
27 | # Can use multiple lines with "-" for bullet points in body
28 | # --------------------
29 | # For more information about this template, check out
30 | # https://gist.github.com/adeekshith/cd4c95a064977cdc6c50
31 |
--------------------------------------------------------------------------------
/git/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Overview
2 |
3 | Please include a summary of the change and which issue is fixed.
4 | Please also include relevant motivation and context.
5 | List any dependencies that are required for this change.
6 |
7 | ## Screenshots
8 |
9 | Visual changes should include a screenshot.
10 |
11 | ## Testing
12 |
13 | 1. instructions for reviewers
14 | 1. to test your changes
15 |
16 | ---
17 |
18 | - Fixes # (issue)
19 | - or [TrelloCard/Issue/Story](LINK_TO_STORY)
20 |
21 | /CC @person
22 |
--------------------------------------------------------------------------------
/javascript/README.md:
--------------------------------------------------------------------------------
1 |
2 | [Airbnb JavaScript Style Guide]: https://github.com/airbnb/javascript
3 |
4 |
5 | [Array Destructuring]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring
6 | [Array Literal Spread Syntax]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_array_literals
7 | [Array.from]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from
8 | [Array.prototype.push]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/push
9 | [Function Arguments Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
10 | [Function Declaration]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function
11 | [Function Default Parameters]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
12 | [Function Expression]: https://developer.mozilla.org/en-US/docs/web/JavaScript/Reference/Operators/function
13 | [No eval]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval!
14 | [NodeList]: https://developer.mozilla.org/en-US/docs/Web/API/NodeList
15 | [Object.assign]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
16 | [Object Destructuring]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring
17 | [Object Literal Spread Syntax]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals
18 | [Spread Syntax]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
19 | [Template Literals]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
20 |
21 |
22 | [Adding Array Items]: https://jsperf.com/adding-array-items
23 | [Arrays from Array-Like Objects]: https://jsperf.com/array-like-object-to-array
24 | [Array Destructuring vs Not]: https://jsperf.com/array-destructuring
25 | [Arrays From Iterables]: https://jsperf.com/arrays-from-iterables
26 | [Mapping Over Iterables]: https://jsperf.com/array-from-vs-spread-vs-array-from-map
27 | [Object Destructuring vs Not]: https://jsperf.com/destructure-vs-not
28 | [Shallow Copy Objects]: https://jsperf.com/shallow-copy-objects
29 | [Shallow Copy Arrays]: https://jsperf.com/shallow-copy-arrays
30 | [Spread Syntax for Variadic Functions]: https://jsperf.com/spread-syntax-for-variadic-functions
31 |
32 |
33 | [array-callback-return]: https://eslint.org/docs/rules/array-callback-return
34 | [function-paren-newline]: https://eslint.org/docs/rules/function-paren-newline
35 | [no-array-constructor]: https://eslint.org/docs/rules/no-array-constructor.html
36 | [no-const-assign]: https://eslint.org/docs/rules/no-const-assign.html
37 | [no-eval]: https://eslint.org/docs/rules/no-eval
38 | [no-new-func]: https://eslint.org/docs/rules/no-new-func
39 | [no-new-object]: https://eslint.org/docs/rules/no-new-object.html
40 | [no-param-reassign]: https://eslint.org/docs/rules/no-param-reassign.html
41 | [no-prototype-builtins]: https://eslint.org/docs/rules/no-prototype-builtins
42 | [no-var]: https://eslint.org/docs/rules/no-var.html
43 | [object-shorthand]: https://eslint.org/docs/rules/object-shorthand.html
44 | [prefer-const]: https://eslint.org/docs/rules/prefer-const.html
45 | [prefer-destructuring]: https://eslint.org/docs/rules/prefer-destructuring
46 | [prefer-object-spread]: https://eslint.org/docs/rules/prefer-object-spread
47 | [prefer-rest-params]: https://eslint.org/docs/rules/prefer-rest-params
48 | [prefer-spread]: https://eslint.org/docs/rules/prefer-spread
49 | [prefer-template]: https://eslint.org/docs/rules/prefer-template.html
50 | [quotes]: https://eslint.org/docs/rules/quotes.html
51 | [quote-props]: https://eslint.org/docs/rules/quote-props.html
52 |
53 |
54 | [@babel/plugin-transform-destructuring]: https://babeljs.io/docs/en/next/babel-plugin-transform-destructuring.html
55 |
56 | # JavaScript Guide
57 |
58 | *A mostly reasonable approach to JavaScript, inspired by the [Airbnb JavaScript Style Guide].*
59 |
60 | ## A note on performance vs readability
61 |
62 | The end-user experience always come first which means performance should always be top-of-mind. The JSPerf examples used in this guide do not use large datasets. If you find yourself working with large datasets and the suggested approach based on this guide performs slower, don't be afraid to push back on a per-project basis (see [Performance vs Readability](https://blog.usejournal.com/performance-vs-readability-2e9332730790)).
63 |
64 | ## Table of Contents
65 |
66 | 1. [Variables](#variables)
67 | 2. [Objects](#objects)
68 | 3. [Arrays](#arrays)
69 | 4. [Destructring](#destructuring)
70 | 5. [Strings](#strings)
71 | 6. [Functions](#functions)
72 |
73 | ---
74 |
75 | ## Variables
76 |
77 | ### 1.1 Prefer Constants
78 |
79 | Use `const` for all of your references; avoid using `var`.
80 |
81 | > Why? This ensures that you can’t reassign your references, which can lead to bugs and difficult to comprehend code.
82 |
83 | #### Examples
84 |
85 | 🚫 Nope. 🚫
86 |
87 | ```js
88 | var a = 1;
89 | var b = 2;
90 | ```
91 |
92 | 🎉 Yep! 🎉
93 |
94 | ```js
95 | const a = 1;
96 | const b = 2;
97 | ```
98 |
99 | #### Resources
100 |
101 | - ESLint:
102 | - [prefer-const]
103 | - [no-const-assign]
104 |
105 | ### 1.2 Reassigning References
106 |
107 | If you must reassign references, use `let` instead of `var`.
108 |
109 | > Why? `let` is block-scoped rather than function-scoped like `var`. Function-scoped variables are hoisted which can lead to bugs if you are not careful. Using block-scoped variables makes our code more predictable by giving the variable an explicit scope.
110 |
111 | #### Examples
112 |
113 | 🚫 Nope. 🚫
114 |
115 | ```js
116 | var count = 1;
117 | if (true) {
118 | count += 1;
119 | }
120 | ```
121 |
122 | 🎉 Yep! 🎉
123 |
124 | ```js
125 | let count = 1;
126 | if (true) {
127 | count += 1;
128 | }
129 | ```
130 |
131 | #### Resources
132 |
133 | - ESLint: [no-var]
134 |
135 | ### 1.3 Block Scope
136 |
137 | Note that both `let` and `const` are block-scoped.
138 |
139 | #### Examples
140 |
141 | ```js
142 | // Both `const` and `let` only exist in the blocks they are defined in.
143 | {
144 | let a = 1;
145 | const b = 1;
146 | }
147 | console.log(a); // ReferenceError: a is not defined
148 | console.log(b); // ReferenceError: b is not defined
149 | ```
150 |
151 | [⇧ top](#javascript-guide)
152 |
153 | ---
154 |
155 | ## Objects
156 |
157 | ### 2.1 Object Creation
158 |
159 | Use the literal syntax for object creation.
160 |
161 | > Why? While there are no performance differences between the two approaches, the byte savings and conciseness of the object literal form is what has made it the de facto way of creating new objects.
162 |
163 | #### Examples
164 |
165 | 🚫 Nope. 🚫
166 |
167 | ```js
168 | const item = new Object();
169 | ````
170 |
171 | 🎉 Yep! 🎉
172 |
173 | ```js
174 | const item = {};
175 | ```
176 |
177 | #### Resources
178 |
179 | - ESLint: [no-new-object]
180 |
181 | ### 2.2 Object Shorthand Syntax
182 |
183 | Use object shorthand syntax for both methods and property values.
184 |
185 | > Why? ECMAScript 6 provides a concise form for defining object literal methods and properties. This syntax can make defining complex object literals much cleaner.
186 |
187 | #### Object Method
188 |
189 | 🚫 Nope. 🚫
190 |
191 | ```js
192 | const atom = {
193 | value: 1,
194 | addValue: function (value) {
195 | return atom.value + value;
196 | },
197 | };
198 | ```
199 |
200 | 🎉 Yep! 🎉
201 |
202 | ```js
203 | const atom = {
204 | value: 1,
205 | addValue(value) {
206 | return atom.value + value;
207 | },
208 | };
209 | ```
210 |
211 | #### Object Property
212 |
213 | 🚫 Nope. 🚫
214 |
215 | ```js
216 | const generalLeiaOrgana = 'General Leia Organa';
217 |
218 | const obj = {
219 | generalLeiaOrgana: generalLeiaOrgana,
220 | };
221 | ```
222 |
223 | 🎉 Yep! 🎉
224 |
225 | ```js
226 | const generalLeiaOrgana = 'General Leia Organa';
227 |
228 | const obj = {
229 | generalLeiaOrgana,
230 | };
231 | ```
232 |
233 | #### Resources
234 |
235 | - ESLint: [object-shorthand]
236 |
237 | ### 2.3 Object Quoted Properties
238 |
239 | Only quote properties that are invalid identifiers.
240 |
241 | > Why? In general we consider it subjectively easier to read. It improves syntax highlighting, and is also more easily optimized by many JS engines.
242 |
243 | #### Examples
244 |
245 | 🚫 Nope. 🚫
246 |
247 | ```js
248 | const obj = {
249 | 'foo': 3,
250 | 'bar': 4,
251 | 'data-blah': 5,
252 | };
253 | ```
254 |
255 | 🎉 Yep! 🎉
256 |
257 | ```js
258 | const obj = {
259 | foo: 3,
260 | bar: 4,
261 | 'data-blah': 5,
262 | };
263 | ```
264 |
265 | #### Resources
266 |
267 | - ESLint: [quote-props]
268 |
269 | ### 2.4 Object Prototype Methods
270 |
271 | Do not call `Object.prototype` methods directly, such as `hasOwnProperty`, `propertyIsEnumerable`, and `isPrototypeOf`.
272 |
273 | > Why? In ECMAScript 5.1, `Object.create` was added, which enables the creation of objects with a specified `[[Prototype]]`. `Object.create(null)` is a common pattern used to create objects that will be used as a Map. This can lead to errors when it is assumed that objects will have properties from `Object.prototype`.
274 |
275 | #### Examples
276 |
277 | 🚫 Nope. 🚫
278 |
279 | ```js
280 | console.log(object.hasOwnProperty(key));
281 | ```
282 |
283 | 🎉 Yep! 🎉
284 |
285 | ```js
286 | // Good
287 | console.log(Object.prototype.hasOwnProperty.call(object, key));
288 |
289 | // Best
290 | const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
291 | console.log(has.call(object, key));
292 | ```
293 |
294 | #### Resources
295 |
296 | - ESLint: [no-prototype-builtins]
297 |
298 | ### 2.5 Object Shallow-Copy
299 |
300 | Prefer the [object spread][Object Literal Spread Syntax] operator over [`Object.assign`][Object.assign] to shallow-copy objects. Use the object rest operator to get a new object with certain properties omitted.
301 |
302 | > Why? Object spread is a declarative alternative which may perform better than the more dynamic, imperative Object.assign.
303 |
304 | #### Examples
305 |
306 | 🚫 Nope. 🚫
307 |
308 | ```js
309 | // This mutates `original` ಠ_ಠ
310 | const original = { a: 1, b: 2 };
311 | const copy = Object.assign(original, { c: 3 });
312 | delete copy.a; // So does this!
313 |
314 | // Works but not preferred
315 | const original = { a: 1, b: 2 };
316 | const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }
317 | ```
318 |
319 | 🎉 Yep! 🎉
320 |
321 | ```js
322 | const original = { a: 1, b: 2 };
323 | const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }
324 |
325 | const { a, ...noA } = copy; // noA => { b: 2, c: 3 }
326 | ```
327 |
328 | #### Resources
329 |
330 | - ESLint: [prefer-object-spread]
331 | - JSPerf: [Shallow Copy Objects]
332 |
333 | [⇧ top](#javascript-guide)
334 |
335 | ---
336 |
337 | ## Arrays
338 |
339 | ### 3.1 Array Creation
340 |
341 | Use the literal syntax for array creation.
342 |
343 | > Why? Use of the `Array` constructor to construct a new array is generally discouraged in favor of array literal notation because of the single-argument pitfall and because the `Array` global may be redefined.
344 |
345 | #### Examples
346 |
347 | 🚫 Nope. 🚫
348 |
349 | ```js
350 | const items = new Array();
351 | ```
352 |
353 | 🎉 Yep! 🎉
354 |
355 | ```js
356 | const items = [];
357 | ```
358 |
359 | #### Resources
360 |
361 | - ESLint: [no-array-constructor]
362 |
363 |
364 | ### 3.2 Adding Items To Arrays
365 |
366 | Use [Array.prototype.push()][Array.prototype.push] instead of direct assignment to add items to an array.
367 |
368 | #### Examples
369 |
370 | 🚫 Nope. 🚫
371 |
372 | ```js
373 | const someStack = [];
374 | someStack[someStack.length] = 'abracadabra';
375 | ```
376 |
377 | 🎉 Yep! 🎉
378 |
379 | ```js
380 | const someStack = [];
381 | someStack.push('abracadabra');
382 | ```
383 |
384 | #### Resources
385 |
386 | - JSPerf: [Adding Array Items]
387 |
388 | ### 3.3 Array Shallow-Copy
389 |
390 | Use [array spread syntax][Array Literal Spread Syntax] `...` to shallow-copy arrays.
391 |
392 | > Why? Better overall performance.
393 |
394 | #### Examples
395 |
396 | 🚫 Nope. 🚫
397 |
398 | ```js
399 | // Too slow
400 | const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
401 | const len = animals.length;
402 | const animalsCopy = [];
403 | let i;
404 |
405 | for (i = 0; i < len; i ++) {
406 | animalsCopy[i] = animals[i];
407 | }
408 |
409 | // Works but is not preferred
410 | const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
411 | const animalsCopy = animals.slice();
412 | ```
413 |
414 | 🎉 Yep! 🎉
415 |
416 | ```js
417 | const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
418 | const animalsCopy = [...animals];
419 | ```
420 |
421 | #### Resources:
422 |
423 | - JSPerf: [Shallow Copy Arrays]
424 |
425 | ### 3.4 Arrays From Iterables
426 |
427 | To convert an iterable object (e.g. [NodeList]) to an array, use [array spread syntax][Array Literal Spread Syntax] `...` instead of [Array.from].
428 |
429 | > Why? Better performance.
430 |
431 | #### Examples
432 |
433 | 🚫 Nope. 🚫
434 |
435 | ```js
436 | const paragraphs = document.querySelectorAll('p');
437 | const nodes = Array.from(paragraphs);
438 | ```
439 |
440 | 🎉 Yep! 🎉
441 |
442 | ```js
443 | const paragraphs = document.querySelectorAll('p');
444 | const nodes = [...paragraphs];
445 | ```
446 | #### Note
447 |
448 | If using Babel with `@babel/preset-env` with option `loose:true`, and are transpiling to older targets in a `.browserlistrc`, you may need to add the following to your Babel config (e.g., `babel.config.js`):
449 |
450 | ```js
451 | plugins: [
452 | ...,
453 | '@babel/plugin-transform-spread',
454 | ...
455 | ]
456 | ```
457 |
458 | (The default option for this plugin is `loose:false`, which will override the global setting)
459 |
460 | #### Resources
461 |
462 | - ESLint: [prefer-spread]
463 | - JSPerf: [Arrays From Iterables]
464 |
465 | ### 3.5 Arrays from Array-Like Objects
466 |
467 | Use [`Array.from`][Array.from] for converting an array-like object to an array.
468 |
469 | > Why? Not only is it easier to read/type but it also performs better.
470 |
471 | #### Examples
472 |
473 | 🚫 Nope. 🚫
474 |
475 | ```js
476 | const arrLike = { 0: 'foo', 1: 'bar', 2: 'baz', length: 3 };
477 | const arr = Array.prototype.slice.call(arrLike);
478 | ```
479 |
480 | 🎉 Yep! 🎉
481 |
482 | ```js
483 | const arrLike = { 0: 'foo', 1: 'bar', 2: 'baz', length: 3 };
484 | const arr = Array.from(arrLike);
485 | ```
486 |
487 | #### Resources
488 |
489 | - JSPerf: [Arrays from Array-Like Objects]
490 |
491 | ### 3.6 Mapping Over Iterables
492 |
493 | Use [array spread syntax][Array Literal Spread Syntax] `...` instead of [`Array.from`][Array.from] for mapping over iterables.
494 |
495 | > Why? Overall better performance.
496 |
497 | #### Examples
498 |
499 | 🚫 Nope. 🚫
500 |
501 | ```js
502 | const iterable = 'Hello there!';
503 | const upperCase = letter => letter.toUpperCase();
504 | const upperCaseLetters = Array.from(iterable, upperCase);
505 | ```
506 |
507 | 🎉 Yep! 🎉
508 |
509 | ```js
510 | const iterable = 'Hello there!';
511 | const upperCase = letter => letter.toUpperCase();
512 | const upperCaseLetters = [...iterable].map(upperCase);
513 | ```
514 |
515 | #### Resources
516 |
517 | - JSPerf: [Mapping Over Iterables]
518 |
519 | ### 3.7 Array Callback Return
520 |
521 | Use `return` statements in array method callbacks. It’s okay to omit the `return` if the function body consists of a single statement returning an expression without side effects.
522 |
523 |
524 | #### Examples
525 |
526 | 🚫 Nope. 🚫
527 |
528 | ```js
529 | inbox.filter(msg => {
530 | const { subject, author } = msg;
531 | if (subject === 'Mockingbird') {
532 | return author === 'Harper Lee';
533 | } else {
534 | return false;
535 | }
536 | });
537 | ```
538 |
539 | 🎉 Yep! 🎉
540 |
541 | ```js
542 | inbox.filter(msg => {
543 | const { subject, author } = msg;
544 | if (subject === 'Mockingbird') {
545 | return author === 'Harper Lee';
546 | }
547 |
548 | return false;
549 | });
550 | ```
551 |
552 | 🎉 Also good! 🎉
553 |
554 | ```js
555 | [1, 2, 3].map((x) => {
556 | const y = x + 1;
557 | return x * y;
558 | });
559 |
560 | // The return can be omitted here.
561 | [1, 2, 3].map(x => x + 1);
562 | ```
563 |
564 | #### Resources
565 |
566 | - ESLint: [array-callback-return]
567 |
568 | [⇧ top](#javascript-guide)
569 |
570 | ---
571 |
572 | ## Destructuring
573 |
574 | ### 4.1 Object Destructuring
575 |
576 | Use [object destructuring][Object Destructuring] when accessing and using multiple properties of an object.
577 |
578 | > Why? Destructuring saves you from creating temporary references for those properties.
579 |
580 | #### Examples
581 |
582 | 🚫 Nope. 🚫
583 |
584 | ```js
585 | function getFullName(user) {
586 | const firstName = user.firstName;
587 | const lastName = user.lastName;
588 |
589 | return `${firstName} ${lastName}`;
590 | }
591 | ```
592 |
593 | 🎉 Yep! 🎉
594 |
595 | ```js
596 | // Good
597 | function getFullName(user) {
598 | const { firstName, lastName } = user;
599 | return `${firstName} ${lastName}`;
600 | }
601 |
602 | // Best
603 | function getFullName({ firstName, lastName }) {
604 | return `${firstName} ${lastName}`;
605 | }
606 | ```
607 |
608 | #### Resources
609 |
610 | - ESLint: [prefer-destructuring]
611 | - JSPerf: [Object Destructuring vs Not]
612 | - MDN Web Docs: [Object Destructuring]
613 |
614 | ### 4.2 Array Destructuring
615 |
616 | How you destructure an array depends on your situation. Below are a couple of ways to complete the same task.
617 |
618 | #### Examples
619 |
620 | ```js
621 | // This works!
622 | const arr = [1, 2, 3, 4];
623 | const first = arr[0];
624 | const second = arr[1];
625 | const rest = arr.slice(2);
626 |
627 | console.log(first); // 1
628 | console.log(second); // 2
629 | console.log(rest); // [3, 4]
630 |
631 | // This works great also!
632 | const arr = [1, 2, 3, 4];
633 | const [first, second, ...rest] = arr;
634 |
635 | console.log(first); // 1
636 | console.log(second); // 2
637 | console.log(rest); // [3, 4]
638 | ```
639 |
640 | _**Note:** For performance reasons, strongly consider use of the [@babel/plugin-transform-destructuring] plugin when using [array destructuring][Array Destructuring]._
641 |
642 | #### Resources
643 |
644 | - Babel Plugin: [@babel/plugin-transform-destructuring]
645 | - JSPerf: [Array Destructuring vs Not]
646 | - MDN Web Docs: [Array Destructuring]
647 |
648 | ### 4.3 Destructuring for Multiple Return Values
649 |
650 | Use [object destructuring][Object Destructuring] for multiple return values, not [array destructuring][Array Destructuring].
651 |
652 | > Why? You can add new properties over time or change the order of things without breaking call sites.
653 |
654 | #### Examples
655 |
656 | 🚫 Nope. 🚫
657 |
658 | ```js
659 | function processInput(input) {
660 | return [left, right, top, bottom];
661 | }
662 |
663 | // the caller needs to think about the order of return data
664 | const [left, __, top] = processInput(input);
665 | ```
666 |
667 | 🎉 Yep! 🎉
668 |
669 | ```js
670 | function processInput(input) {
671 | return { left, right, top, bottom };
672 | }
673 |
674 | // the caller selects only the data they need
675 | const { left, top } = processInput(input);
676 | ```
677 |
678 | [⇧ top](#javascript-guide)
679 |
680 | ---
681 |
682 | ## Strings
683 |
684 | ### 5.1 Quotes
685 |
686 | Use single quotes `''` for strings. The exception is if a string includes a literal `'` single quote, use double quotes `"` instead.
687 |
688 | #### Examples
689 |
690 | 🚫 Nope. 🚫
691 |
692 | ```js
693 | // Should be single quote.
694 | const name = "Cloud Four";
695 |
696 | // Template literals should contain interpolation or newlines.
697 | const name = `Cloud Four`;
698 |
699 | // This string has a literal single quote!
700 | const foo = 'What\'s for dinner?';
701 | ```
702 |
703 | 🎉 Yep! 🎉
704 |
705 | ```js
706 | const name = 'Cloud Four';
707 |
708 | // It's okay to use double quotes here.
709 | const foo = "What's for dinner?";
710 | ```
711 |
712 | #### Resources
713 |
714 | - ESLint: [quotes]
715 |
716 | ### 5.2 Template Literals
717 |
718 | When programmatically building up strings, use [template literals][Template Literals] instead of concatenation.
719 |
720 | > Why? Template literals (template strings) give you a readable, concise syntax with proper newlines and string interpolation features.
721 |
722 | #### Examples
723 |
724 | 🚫 Nope. 🚫
725 |
726 | ```js
727 | function sayHi(name) {
728 | return 'How are you, ' + name + '?';
729 | }
730 |
731 | function sayHi(name) {
732 | return ['How are you, ', name, '?'].join();
733 | }
734 | ```
735 |
736 | 🎉 Yep! 🎉
737 |
738 | ```js
739 | function sayHi(name) {
740 | return `How are you, ${name}?`;
741 | }
742 | ```
743 |
744 | #### Resources
745 |
746 | - ESLint: [prefer-template]
747 |
748 | ### 5.3 Eval
749 |
750 | [Never use `eval()`][No eval] on a string, it opens too many vulnerabilities.
751 |
752 | #### Resources
753 |
754 | - ESLint: [no-eval]
755 |
756 | [⇧ top](#javascript-guide)
757 |
758 | ---
759 |
760 | ## Functions
761 |
762 | ### 6.1 Avoid Function Hoisting
763 |
764 | Although it is possible to call functions before they are defined via [hoisting](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) we prefer to avoid this pattern in our code as it can be confusing.
765 |
766 | #### Examples
767 |
768 | Although this code works properly it may be more confusing and we generally avoid it:
769 |
770 | ```js
771 | logFoo();
772 |
773 | function logFoo() {
774 | console.log("foo");
775 | }
776 | ```
777 |
778 | We would prefer one of the following patterns:
779 |
780 | ```js
781 | // Define the function before calling
782 | function logFoo() {
783 | console.log("foo");
784 | }
785 |
786 | logFoo();
787 | ```
788 |
789 | ```js
790 | // Import the function
791 | import {logFoo} from './log-foo.js';
792 |
793 | logFoo();
794 | ```
795 |
796 | In files that call a number of helper functions it can be helpful to move those functions to modules, or start the file with a main function that provides a summary of the steps taken in the file. For example:
797 |
798 | ```js
799 | // The `main` function contains an overview of the file's logic.
800 | // (`main` could be switched to a more meaningful name in context.)
801 | function main() {
802 | thing1();
803 | thing2();
804 | thing3();
805 | thing4();
806 | }
807 |
808 | function thing1() {}
809 | function thing2() {}
810 | function thing3() {}
811 | function thing4() {}
812 |
813 | main();
814 | ```
815 |
816 | Another option is to move helper functions to modules:
817 |
818 | ```js
819 | // Import helpers so they're defined up front
820 | import {thing1, thing2, thing3, thing4} from './helpers.js';
821 |
822 | thing1();
823 | thing2();
824 | thing3();
825 | thing4();
826 | ```
827 |
828 | ### 6.2 Function Arguments Parameter
829 |
830 | Never name a function parameter `arguments`.
831 |
832 | > Why? This will take precedence over the [`arguments` object][Function Arguments Object] that is given to every function scope.
833 |
834 | #### Examples
835 |
836 | 🚫 Nope. 🚫
837 |
838 | ```js
839 | function foo(name, options, arguments) {
840 | // ...
841 | }
842 | ```
843 |
844 | 🎉 Yep! 🎉
845 |
846 | ```js
847 | function foo(name, options, args) {
848 | // ...
849 | }
850 | ```
851 |
852 | #### Resources
853 |
854 | - MDN: [Function Arguments Object]
855 |
856 | ### 6.3 Use Rest Syntax for Function Arguments Object
857 |
858 | Use the rest syntax `...args` instead of the `arguments` object.
859 |
860 | > Why? Rest arguments are a real Array, and not merely Array-like as the `arguments` object is.
861 |
862 | #### Examples
863 |
864 | 🚫 Nope. 🚫
865 |
866 | ```js
867 | function concatenateAll() {
868 | const args = Array.prototype.slice.call(arguments);
869 | return args.join('');
870 | }
871 |
872 | // Slow performance
873 | function concatenateAll() {
874 | const args = Array.from(arguments);
875 | return args.join('');
876 | }
877 | ```
878 |
879 | 🎉 Yep! 🎉
880 |
881 | ```js
882 | function concatenateAll(...args) {
883 | return args.join('');
884 | }
885 | ```
886 |
887 | #### Resources
888 |
889 | - ESLint: [prefer-rest-params]
890 |
891 | ### 6.4 Function Default Parameters
892 |
893 | Use [function default parameter syntax][Function Default Parameters] rather than mutating function arguments.
894 |
895 | #### Examples
896 |
897 | 🚫 Nope. 🚫
898 |
899 | ```js
900 | function doThings(opts) {
901 | // If opts is falsey it can introduce bugs.
902 | opts = opts || {};
903 | // ...
904 | }
905 |
906 | function doThings(opts) {
907 | if (opts === undefined) {
908 | opts = {};
909 | }
910 | // ...
911 | }
912 | ```
913 |
914 | 🎉 Yep! 🎉
915 |
916 | ```js
917 | function doThings(opts = {}) {
918 | // ...
919 | }
920 | ```
921 |
922 | #### Resources
923 |
924 | - MDN: [Function Default Parameters]
925 |
926 | ### 6.5 Function Default Parameter Side Effects
927 |
928 | Avoid side effects with [function default parameters][Function Default Parameters].
929 |
930 | > Why? They are confusing to reason about.
931 |
932 | #### Examples
933 |
934 | 🚫 Nope. 🚫
935 |
936 | ```js
937 | let b = 1;
938 |
939 | // Eek!
940 | function count(a = b++) {
941 | console.log(a);
942 | }
943 |
944 | count(); // 1
945 | count(); // 2
946 | count(3); // 3
947 | count(); // 3
948 | ```
949 |
950 | ### 6.6 Function Constructor
951 |
952 | Never use the `Function` constructor to create a new function.
953 |
954 | > Why? Creating a function in this way evaluates a string similarly to `eval()`, which [opens vulnerabilities](#53-eval).
955 |
956 | #### Examples
957 |
958 | 🚫 Nope. 🚫
959 |
960 | ```js
961 | var add = new Function('a', 'b', 'return a + b');
962 |
963 | var subtract = Function('a', 'b', 'return a - b');
964 | ```
965 |
966 | 🎉 Yep! 🎉
967 |
968 | ```js
969 | var x = function (a, b) {
970 | return a + b;
971 | };
972 | ```
973 |
974 | #### Resources
975 |
976 | - ESLint: [no-new-func]
977 |
978 | ### 6.7 Mutating Function Parameters
979 |
980 | Never mutate function parameters.
981 |
982 | > Why? Manipulating objects passed in as parameters can cause unwanted variable side effects in the original caller.
983 |
984 | #### Examples
985 |
986 | 🚫 Nope. 🚫
987 |
988 | ```js
989 | function foo(bar) {
990 | bar = 13;
991 | }
992 |
993 | function foo(bar) {
994 | bar++;
995 | }
996 | ```
997 |
998 | 🎉 Yep! 🎉
999 |
1000 | ```js
1001 | function foo(bar) {
1002 | var baz = bar;
1003 | }
1004 | ```
1005 |
1006 | #### Resources
1007 |
1008 | - ESLint: [no-param-reassign]
1009 |
1010 |
1011 | ### 6.8 Spread Syntax for Variadic Functions
1012 |
1013 | Prefer the use of the [spread syntax operator `...`][Spread Syntax] to call variadic functions (a function that accepts a variable number of arguments).
1014 |
1015 | > Why? It’s cleaner, you don’t need to supply a context, and it's easier to compose `new` when compared to using `apply`.
1016 |
1017 | #### Examples
1018 |
1019 | 🚫 Nope. 🚫
1020 |
1021 | ```js
1022 | const args = [1, 2, 3, 4];
1023 | Math.max.apply(Math, args);
1024 |
1025 | new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));
1026 | ```
1027 |
1028 | 🎉 Yep! 🎉
1029 |
1030 | ```js
1031 | const args = [1, 2, 3, 4];
1032 | Math.max(...args);
1033 |
1034 | new Date(...[2016, 8, 5]);
1035 | ```
1036 |
1037 | #### Resources
1038 |
1039 | - ESLint: [prefer-spread]
1040 | - JSPerf: [Spread Syntax for Variadic Functions]
1041 |
1042 | [⇧ top](#javascript-guide)
1043 |
1044 | ---
1045 |
1046 | ## Arrow Functions
1047 |
1048 | TBD...
1049 |
1050 | [⇧ top](#javascript-guide)
1051 |
1052 | ---
1053 |
1054 | ## Classes & Constructors
1055 |
1056 | TBD...
1057 |
1058 | [⇧ top](#javascript-guide)
1059 |
1060 | ---
1061 |
1062 | ## Modules
1063 |
1064 | TBD...
1065 |
1066 | [⇧ top](#javascript-guide)
1067 |
1068 | ---
1069 |
1070 | ## Iterators and Generators
1071 |
1072 | TBD...
1073 |
1074 | [⇧ top](#javascript-guide)
1075 |
1076 | ---
1077 |
1078 | ## Properties
1079 |
1080 | TBD...
1081 |
1082 | [⇧ top](#javascript-guide)
1083 |
1084 | ---
1085 |
1086 | ## Variables
1087 |
1088 | TBD...
1089 |
1090 | [⇧ top](#javascript-guide)
1091 |
1092 | ---
1093 |
1094 | ## Hoisting
1095 |
1096 | TBD...
1097 |
1098 | [⇧ top](#javascript-guide)
1099 |
1100 | ---
1101 |
1102 | ## Comparison Operators & Equality
1103 |
1104 | TBD...
1105 |
1106 | [⇧ top](#javascript-guide)
1107 |
1108 | ---
1109 |
1110 | ## Blocks
1111 |
1112 | TBD...
1113 |
1114 | [⇧ top](#javascript-guide)
1115 |
1116 | ---
1117 |
1118 | ## Control Statements
1119 |
1120 | TBD...
1121 |
1122 | [⇧ top](#javascript-guide)
1123 |
1124 | ---
1125 |
1126 | ## Comments
1127 |
1128 | TBD...
1129 |
1130 | [⇧ top](#javascript-guide)
1131 |
1132 | ---
1133 |
1134 | ## Whitespace
1135 |
1136 | TBD...
1137 |
1138 | [⇧ top](#javascript-guide)
1139 |
1140 | ---
1141 |
1142 | ## Commas
1143 |
1144 | TBD...
1145 |
1146 | [⇧ top](#javascript-guide)
1147 |
1148 | ---
1149 |
1150 | ## Semicolons
1151 |
1152 | TBD...
1153 |
1154 | [⇧ top](#javascript-guide)
1155 |
1156 | ---
1157 |
1158 | ## Type Casting & Coercion
1159 |
1160 | TBD...
1161 |
1162 | [⇧ top](#javascript-guide)
1163 |
1164 | ---
1165 |
1166 | ## Naming Conventions
1167 |
1168 | TBD...
1169 |
1170 | [⇧ top](#javascript-guide)
1171 |
1172 | ---
1173 |
1174 | ## Accessors
1175 |
1176 | TBD...
1177 |
1178 | [⇧ top](#javascript-guide)
1179 |
1180 | ---
1181 |
1182 | ## Events
1183 |
1184 | TBD...
1185 |
1186 | [⇧ top](#javascript-guide)
1187 |
1188 | ---
1189 |
1190 | ## jQuery
1191 |
1192 | TBD...
1193 |
1194 | [⇧ top](#javascript-guide)
1195 |
1196 | ---
1197 |
1198 | ## ECMAScript 5 Compatibility
1199 |
1200 | TBD...
1201 |
1202 | [⇧ top](#javascript-guide)
1203 |
1204 | ---
1205 |
1206 | ## ECMAScript 6+ (ES 2015+) Styles
1207 |
1208 | TBD...
1209 |
1210 | [⇧ top](#javascript-guide)
1211 |
1212 | ---
1213 |
1214 | ## Standard Library
1215 |
1216 | TBD...
1217 |
1218 | [⇧ top](#javascript-guide)
1219 |
1220 | ---
1221 |
1222 | ## Testing
1223 |
1224 | TBD...
1225 |
1226 | [⇧ top](#javascript-guide)
1227 |
1228 | ---
1229 |
1230 | ## Performance
1231 |
1232 | TBD...
1233 |
1234 | [⇧ top](#javascript-guide)
1235 |
1236 | ---
1237 |
1238 | ## Resources
1239 |
1240 | TBD...
1241 |
1242 | [⇧ top](#javascript-guide)
1243 |
1244 | ---
1245 |
1246 | ## In the Wild
1247 |
1248 | TBD...
1249 |
1250 | [⇧ top](#javascript-guide)
1251 |
1252 | ---
1253 |
1254 | ## Translation
1255 |
1256 | TBD...
1257 |
1258 | [⇧ top](#javascript-guide)
1259 |
1260 | ---
1261 |
1262 | ## The JavaScript Style Guide Guide
1263 |
1264 | TBD...
1265 |
1266 | [⇧ top](#javascript-guide)
1267 |
1268 | ---
1269 |
1270 | ## Contributors
1271 |
1272 | TBD...
1273 |
1274 | [⇧ top](#javascript-guide)
1275 |
1276 | ---
1277 |
1278 | ## License
1279 |
1280 | TBD...
1281 |
1282 | [⇧ top](#javascript-guide)
1283 |
--------------------------------------------------------------------------------
/javascript/vue/README.md:
--------------------------------------------------------------------------------
1 | # Vue Guide
2 |
3 | This styleguide is a work-in-progress, documenting how Cloud Four prefers to write Vue. As we continue to expand it, please refer to these guides for additional best practices:
4 |
5 | * [Official Vue Style Guide](https://vuejs.org/v2/style-guide/)
6 | * [Deverus Vue Style Guide](https://gist.github.com/brianboyko/91fdfb492071e743e389d84eee002342)
7 | * [Erik reviews the Deverus Style Guide](https://www.youtube.com/watch?v=38XnZ3EJqYQ)
8 |
9 | ## Destructuring in Templates
10 |
11 | Try to avoid destructuring in HTML templates, to make it obvious where a particular variable is coming from. Since HTML templates have access to props and local variables in `v-for` loops, clarity is favored over brevity in this case.
12 |
13 | ### Avoid This
14 |
15 | Notice that in this example with nested `v-for` loops, destructuring makes it unclear where certain variables are coming from, and some repeated variables like `title` need to be remapped.
16 |
17 | ```vue
18 |
19 |
{{ title }}
20 |
21 |
25 |
{{ subtitle }}
26 |
27 |
28 | {{ question }}
29 |
{{ answer }}
30 |
31 |
32 |
33 |
34 | {{ question }}
35 |
{{ answer }}
36 |
37 |
38 | ```
39 |
40 | ### Prefer This
41 |
42 | By not destructuring, the nested `v-for` loops are much easier to understand.
43 |
44 | ```vue
45 |
46 |
{{ category.title }}
47 |
48 |
49 |
{{ subcategory.title }}
50 |
51 |
52 | {{ item.question }}
53 |
{{ item.answer }}
54 |
55 |
56 |
57 |
58 | {{ item.question }}
59 |
{{ item.answer }}
60 |
61 |
62 | ```
63 |
64 | Note that while these examples with nested `v-for` loops are extreme, they highlight a possible problem with destructuring in HTML templates. As a team, we decided to favor consistency, and rather than have a rule like "always destructure except in loops," we've standardized on "avoid destructuring in templates."
65 |
--------------------------------------------------------------------------------
/learning/javascript/README.md:
--------------------------------------------------------------------------------
1 | # Learning JavaScript
2 |
3 | *Note*: Right now this is just a catch-all place for some JavaScript learning resources and scribbly notes. I may continue to organize this more formally as we go. The sections will be based roughly on the excellent [_Eloquent JavaScript_](http://eloquentjavascript.net/) by Martijn Haverbeke.
4 |
5 | # JavaScript, Introduction
6 |
7 | Read the [Introduction chapter of _Eloquent JavaScript_](http://eloquentjavascript.net/00_intro.html).
8 |
9 | ## *What is JavaScript?* and Terminology
10 |
11 | ### ECMA
12 |
13 | The chapter makes mention of ECMA and ECMAScript. These are terms you’ll hear a lot. Developers often abbreviate “ECMAScript” to _ES_, as in _ES5_ and _ES6_ (both in written and spoken forms).
14 |
15 | ES6 (ECMAScript 6, also known as “Harmony”) is a big, hot topic right now. We’ll be talking more about that as we go.
16 |
17 | For now, most of what you’ll see is ES5, the flavor of JavaScript supported by [basically every browser](http://kangax.github.io/compat-table/es5/).
18 |
19 | ### Platforms and Engines
20 |
21 | JavaScript is a language, but it needs a place to be executed. There are several leading JavaScript *engines* ("virtual environments that interpret and execute JavaScript", thanks, Wikipedia!), including:
22 |
23 | * V8 (Chrome, node)
24 | * SpiderMonkey (first JS engine ever; now in Firefox)
25 | * Nitro (Safari)
26 |
27 |
28 | ## An Aside: Matters of Style and Opinion
29 |
30 | Toward the end of the introduction for _Eloquent JavaScript_ is a code block like this:
31 |
32 | ```javascript
33 | function fac(n) {
34 | if (n == 0)
35 | return 1;
36 | else
37 | return fac(n - 1) * n;
38 | }
39 | ```
40 |
41 | Coding style is like writing style and punctuation: different people do it differently. At Cloud Four, we have our own set of conventions for writing JavaScript (and other things, like CSS!) that we try to stick to. In fact, this code block violates one of them.
42 |
43 | We define JavaScript coding conventions at Cloud Four using two tools, [JSHint](http://jshint.com/) and [JSCS](http://jscs.info/).
44 |
45 | JSHint conventions are tuned toward preventing you from making actual programming mistakes, while JSCS conventions are stylistic.
46 |
47 | Configuration files for both JSHint and JSCS are installed automatically on Cloud Four laptops using boxen, and the appropriate plugins/packages for enforcing them are installed for either Atom or SublimeText. In case you are curious, you can [find our current conventions here](https://github.com/cloudfour/cloudfour-boxen/tree/master/modules/cloudfour_potions/files/dotfiles) (`jscsrc` and `jshintrc`).
48 |
49 | ## Exercises
50 |
51 | These let you try out a couple of places that you can go to test JavaScript and inspect the state of the browser environment.
52 |
53 | ### Exercise 1: Web Inspector, the `window` object
54 |
55 | In Chrome, open the Web Inspector (`Option-Cmd-I` on a Mac) and go to the `console` tab.
56 |
57 | Type
58 |
59 | ```javascript
60 | window
61 | ```
62 |
63 | and hit enter.
64 |
65 | What this does is display (print out) a representation of the value for the identifier `window`. `window` is a JavaScript `Object` that is made available by the `environment` in the browser (if "Object" and "environment" are mysterious concepts as of yet, don't fret, they'll come up later).
66 |
67 | Expand the `window` object and explore it a bit, especially the stuff under the `document` property (itself another object...it's objects all the way down!). The `document` object contains representations of a lot of stuff about the web document in the browser window and you may start seeing some items that look familiar here.
68 |
69 | ### Exercise 2: ScratchPad, `window` object redux
70 |
71 | In Firefox, go to `Tools -> Web Developer -> Scratchpad...`. You can [read more about it here](https://developer.mozilla.org/en-US/docs/Tools/Scratchpad) if you like.
72 |
73 | The console in Web Inspector or the Console in Firefox are useful for quick, one-line things (in the previous example, `window` gets evaluated as soon as you hit enter), but ScratchPad gives you the ability to run longer chunks of JavaScript code in the browser environment.
74 |
75 | Type
76 |
77 | ```javascript```
78 | window
79 | ```
80 |
81 | and hit enter.
82 |
83 | Now click the `Run` button. Nothing happens. That's because we're not _in_ the console, the way we were when we were in the Web Inspector console above. This isn't a console, so things aren't logging out (displaying their values). But what if we wanted to examine the `window` object? There are two options. One is to right-click the `window` text and choose `Inspect` from the pop-up menu (this lets you explore the current state of the `window` object on that line).
84 |
85 | #### Exercise Thinking Points
86 |
87 | * What happens if you modify the code in the ScratchPad to read: `console.log(window);` and click `Run`? Can you find the output?
88 | * What is the value of the `window.document.URL` property? What does it refer to?
89 |
90 | ## Questions for Thought
91 |
92 | * Is there a difference between JavaScript and ECMAScript? Why do both exist?
93 | * Explore: What's the relationship between JavaScript and node?
94 |
--------------------------------------------------------------------------------
/npm/README.md:
--------------------------------------------------------------------------------
1 | # Setting up your computer to publish to npm (only necessary the first time)
2 |
3 | Prerequisites: [Node.js](https://github.com/creationix/nvm#installation) with npm version 5.7.0+ (required for `npm ci` to work)
4 |
5 | ## Setting up your npm account online
6 |
7 | - [Either confirm that you have an npm account or create one](https://www.npmjs.com/) (you'll need your username and password)
8 | - Confirm you have set up two-factor authentication on your npm account or set it up
9 | - Set up 2FA to protect `Authorization and Publishing`
10 | - Use a 2FA provider to complete your 2FA setup ([1Password](https://1password.com/) or [Authy](https://authy.com/) or [Google Authenticator](https://itunes.apple.com/us/app/google-authenticator/id388497605?mt=8))
11 | - This app will now provide you with a One-Time Password (OTP), every time you do a task that requires 2FA
12 | - Login to the C4 npm account (see 1Password for details: `cloudfour-user`)
13 | - Go to the account settings for the `cloudfour` npm organization (not `cloudfour-user`)
14 | - Go to the `Members` tab and use `Invite Members` to invite yourself, using the npm username you had or just created
15 | - You may or may not need to logout and go to your account to accept the invite
16 |
17 | ## Signing in to npm locally
18 |
19 | - In the terminal, type `npm adduser `, and enter:
20 | - Your username
21 | - Your password
22 | - Your email address
23 | - A new OTP from your phone, once prompted
24 |
25 | Once you are signed in, you should be ready to publish (see individual repos for per-repo publishing instructions)
26 |
--------------------------------------------------------------------------------
/opensource/README.md:
--------------------------------------------------------------------------------
1 | # Open Source at Cloud Four
2 |
3 | This guide is about how we manage our open-source work at Cloud Four. Given that this work happens across several Git repos that have been set up by various people over many years, it makes sense to have a guide that documents our current best thinking about how to operate them.
4 |
5 | ## NPM Package Setup
6 |
7 | !!! THIS IS A WORK-IN-PROGRESS !!!
8 |
9 | For open-source work that is published to npm, we need to do our due diligence. That includes ensuring that the package has tests, the build passes, there are no security vulnerabilities, and it stays up-to-date with dependencies.
10 |
11 | - [@cloudfour npm packages](https://www.npmjs.com/org/cloudfour)
12 |
13 | ### Checklist
14 |
15 | - [ ] one
16 | - [ ] two
17 | - [ ] three
18 |
19 | ### README file
20 |
21 | Add note about recommended README bits:
22 |
23 | - npm badge
24 | - build status badge
25 | - install instructions (from npm)
26 | - link to documentation
27 | - link to changelog
28 |
29 | ### CHANGELOG file
30 |
31 | Add note about the importance of maintaining a changelog.
32 |
33 | ### Release Process
34 |
35 | Add note about version bump and npm release process
36 |
37 | - [bump](https://github.com/fabiospampinato/bump)
38 |
39 | ### Tests & Linting
40 |
41 | Add note about testing and linting
42 |
43 | ### Continuous Integration
44 |
45 | Add note about Travis (and .com/.org) to run tests and lint
46 |
47 | ### Automated Dependency Updates
48 |
49 | Add note about Renovate
50 |
51 | - How to evaluate Renovate PRs
52 |
53 | ### Automated Security Checks
54 |
55 | Add note about Snyk
56 |
57 | - Added by Jason in April 2017. Company was started by a friend of his, and some good people work there.
58 | - How to evaluate Snyk security patches
59 | - Lifecycle of a Snyk security patch
60 |
61 | - [Snyk documentation](https://snyk.io/docs/)
62 | - [Using Snyk, NSP and Retire.JS to Identify and Fix Vulnerable Dependencies in your Node.js Applications](https://developers.redhat.com/blog/2017/04/12/using-snyk-nsp-and-retire-js-to-identify-and-fix-vulnerable-dependencies-in-your-node-js-applications/)
63 | - [NSP is shutting down](https://blog.npmjs.org/post/175511531085/the-node-security-platform-service-is-shutting)
64 | - [Introducing `npm audit`: Identify and fix insecure dependencies](https://blog.npmjs.org/post/173719309445/npm-audit-identify-and-fix-insecure)
65 | - [Difference between Snyk and NSP?](https://github.com/Snyk/snyk/issues/19)
66 | - [Audit CI](https://www.npmjs.com/package/audit-ci)
67 | - [Comparing NPM Audit with Synk](https://www.nearform.com/blog/comparing-npm-audit-with-snyk/)
68 | - [Snyk demo app](https://github.com/snyk/snyk-demo-app)
69 | - [Twitter thread about Snyk patches](https://twitter.com/spaceninja/status/1118179340871553024)
70 |
--------------------------------------------------------------------------------
/package-json-script-names.md:
--------------------------------------------------------------------------------
1 | # `package.json` Script Names
2 |
3 | ## General
4 |
5 | - `npm run validate`: Runs all tests, type checks, linters, and formatters
6 |
7 | ## Testing
8 |
9 | - `npm run test`: Runs all test runners (Jest and/or Cypress)
10 | - `npm run test:watch`: Runs all test runners in watch mode
11 | - `npm run test:jest`: Runs Jest and exits
12 | - `npm run test:jest:watch`: Runs Jest in watch mode
13 | - `npm run test:cypress`: Runs Cypress and exits
14 | - `npm run test:cypress:open`: Open Cypress dashboard
15 |
16 | ## Linting
17 |
18 | - `npm run lint`: Runs all linters and formatters, and fixes any auto-fixable problems
19 | - `npm run lint:check`: Runs all linters and formatters, and reports problems even if they are auto-fixable
20 | - `npm run lint:js`
21 | - `npm run lint:js:check`
22 | - `npm run lint:css`
23 | - `npm run lint:css:check`
24 |
25 | ## Type Checking
26 |
27 | - `npm run type`: Runs typechecker
28 | - `npm run type:watch`: Runs the typechecker in watch mode
29 |
--------------------------------------------------------------------------------
/rituals/README.md:
--------------------------------------------------------------------------------
1 | # Rituals
2 |
3 | This guide documents some common rituals we encourage in our work.
4 |
5 | These are not ironclad processes we should always follow. More like a helpful jumping-off point if you're on a project where they would be useful.
6 |
7 | ## [Postmortems](./postmortems.md)
8 |
9 | > “A postmortem is a written record of an incident, its impact, the actions taken to mitigate or resolve it, the root cause(s), and the follow-up actions to prevent the incident from recurring.” — Google's _Site Reliability Engineering_
10 |
11 | This ritual is held when a serious incident happens, such as a site outage, and the team needs to understand what happened and how to avoid it in the future.
12 |
--------------------------------------------------------------------------------
/rituals/postmortems.md:
--------------------------------------------------------------------------------
1 | # Incident Postmortems
2 |
3 | Postmortem documents are a ritual designed to examine serious incidents or outages. Google’s [book on Site Reliability Engineering](https://landing.google.com/sre/book.html) says:
4 |
5 | > A postmortem is a written record of an incident, its impact, the actions taken to mitigate or resolve it, the root cause(s), and the follow-up actions to prevent the incident from recurring.
6 |
7 | ## Purpose
8 |
9 | We practice postmortems to ensure we understand and address the root cause of severe incidents such as outages, data loss, or serious production bugs.
10 |
11 | > "Don't make the mistake of neglecting a post-mortem after an incident. Without a post-mortem you fail to recognize what you're doing right, where you could improve, and most importantly, how to avoid making the same exact mistakes next time around. A well-designed, blameless post-mortem allows teams to continuously learn, and serves as a way to iteratively improve your infrastructure and incident response process." — [PagerDuty](https://response.pagerduty.com/after/post_mortem_process/)
12 |
13 | ### What is a Postmortem?
14 |
15 | A postmortem is a document that examines an incident in detail, including:
16 |
17 | - An summary of what happened
18 | - The incident's impact
19 | - What caused the incident
20 | - How the incident was resolved
21 | - A detailed timeline
22 | - What could have prevented the incident
23 |
24 | ### Why Do We Do Postmortems?
25 |
26 | The goal of the postmortem is to gain a detailed understanding of the root causes of the incident to avoid it happening again in the future. A secondary goal can be to reassure the client, since the actions taken during an incident response may not be visible to them.
27 |
28 | For postmortems to be effective at reducing repeat incidents, the review process has to incentivize teams to honestly identify root causes and fix them. For this reason, we practice **blameless postmortems** (see below).
29 |
30 | ### When is a Postmortem Needed?
31 |
32 | It depends on the client or project. For applications or sites with an service-level agreement, postmortems are commonly carried out for high-severity incidents that violate the SLA. For client applications or site, a postmortem may only be called for following a major outage or quality-control problem.
33 |
34 | > "Incidents in your organization should have clear and measurable severity levels. These severity levels can be used to trigger the post-mortem process. For example, any incident Sev-1 or higher triggers the postmortem process, while the postmortem can be optional for less severe incidents." — [Atlassian](https://www.atlassian.com/blog/statuspage/incident-postmortem-writing-tips)
35 |
36 | The postmortem document should be produced within 24-48 hours of the incident's resolution, while it's still fresh in everyone's memory.
37 |
38 | > "Despite how painful an outage may have been, the worst thing you can do is to bury it and never properly close the incident in a clear and transparent way. Most humans come together in times of crisis and communication around outage post-mortems, in my experience, has always been met with positive energy, understanding comments, constructive suggestions and numerous offers to help." — [Daniel Doubrovkine says](https://artsy.github.io/blog/2014/11/19/how-to-write-great-outage-post-mortems/)
39 |
40 | ### Who Completes the Postmortem?
41 |
42 | In a small company like ours, the most senior engineer with direct knowledge should be writing an outage postmortem. It's their job and responsibility to acknowledge, understand and explain what happened. For particularly sensitive topics, it may make sense to escalate this responsibility to an engineering manager or founder.
43 |
44 | > "Focusing attention away from the individual contributors allows the team to learn from the mistakes and address the root causes in time without the unnecessary stress or pressure during a crisis." — [Daniel Doubrovkine](https://artsy.github.io/blog/2014/11/19/how-to-write-great-outage-post-mortems/)
45 |
46 | ### Who is the Postmortem For?
47 |
48 | The postmortem is intended for public consumption, especially by clients. It's a visible way to document not just the problem that happened, but how you addressed it and are ensuring it won't happen again. A properly written postmortem should increase your customer's faith in you.
49 |
50 | > "The postmortem audience includes customers, direct reports, peers, the company's executive team and often investors. The document may be published on your website, and otherwise goes to the entire team. It's critical to bcc everyone. This is the equivalent of a locked thread, avoiding washing the laundry in public: one of the worst possible things to see is when a senior manager replies back pointing an individual who made a mistake, definitely not an email you want accidentally sent to the entire company." — [Daniel Doubrovkine](https://artsy.github.io/blog/2014/11/19/how-to-write-great-outage-post-mortems/)
51 |
52 | ### Running a Postmortem Meeting
53 |
54 | Some teams hold a meeting after the postmortem document is produced. These meetings are generally short, only 15-30 minutes, and are intended to be a wrap-up of the postmortem process. We discuss what happened, what could have gone better, and any followup actions we need to take. The point of the meeting is to ensure there's no disagreement on the analysis, and spread a wider awareness of problems the team is facing.
55 |
56 | ## Blameless Postmortems
57 |
58 | Many teams have adopted “blameless” postmortems, which focus on systemic problems and root causes without naming individuals or casting blame onto people or teams. Here's John Allspaw, from [Blameless Postmortems and a Just Culture](https://codeascraft.com/2012/05/22/blameless-postmortems/)
59 |
60 | > Having a “blameless” Post-Mortem process means that engineers whose actions have contributed to an accident can give a detailed account of:
61 |
62 | > - what actions they took at what time,
63 | > - what effects they observed,
64 | > - expectations they had,
65 | > - assumptions they had made,
66 | > - and their understanding of timeline of events as they occurred.
67 |
68 | > …and that they can give this detailed account without fear of punishment or retribution.
69 |
70 | > Why shouldn’t they be punished or reprimanded? Because an engineer who thinks they’re going to be reprimanded are disincentivized to give the details necessary to get an understanding of the mechanism, pathology, and operation of the failure. This lack of understanding of how the accident occurred all but guarantees that it will repeat. If not with the original engineer, another one in the future.
71 |
72 | For a good example of why blameless postmortems matter, I strongly encourage you to watch [Who Destroyed Three Mile Island?](https://www.youtube.com/watch?v=hMk6rF4Tzsg), a talk by Nickolas Means from Lead Dev London 2018.
73 |
74 | ## Tips
75 |
76 | - Make sure the timeline is an accurate representation of events.
77 | - Use the [Five Whys](https://en.wikipedia.org/wiki/5_Whys) technique to traverse the causal chain until you find a good true root cause.
78 | - Don't change details or events to make things "look better". We need to be honest in our post-mortems, even to ourselves, otherwise they lose their effectiveness.
79 | - Don't name and shame someone. We keep our post-mortems blameless. If someone deployed a change that broke things, it's not their fault, it's our fault for having a system that allowed them to deploy a breaking change, etc.
80 | - Avoid the concept of "human error". This is related to the point above about "naming and shaming", but there's a subtle difference - very rarely is the mistake "rooted" in a human performing an action, there are often several contributing factors (the script the human ran didn't have rate limiting, the documentation was out of date, etc...) that can and should be addressed.
81 |
82 | ## Resources
83 |
84 | * [Postmortem Template](https://docs.google.com/document/d/12Prd33SDG1U0yE_gwXUgwa85Vn6dS_Qo5RdEWwFzFEo) document on Google Drive
85 | * [Postmortem Handbook from Atlassian](https://www.atlassian.com/incident-management/handbook/postmortems)
86 | * [Postmortem Process from PagerDuty](https://response.pagerduty.com/after/post_mortem_process/)
87 | * [Effective Postmortem Tips from PagerDuty](https://response.pagerduty.com/after/effective_post_mortems/)
88 | * [Blameless Postmortems and a Just Culture](https://codeascraft.com/2012/05/22/blameless-postmortems/)
89 | * [How to Write Great Outage Postmortems](https://artsy.github.io/blog/2014/11/19/how-to-write-great-outage-post-mortems/)
90 |
--------------------------------------------------------------------------------
/testing/README.md:
--------------------------------------------------------------------------------
1 | # Testing
2 |
3 | ## Philosophy
4 | * Test code is a first-class part of the deliverable, not an optional nice-to-have.
5 | * When scoping / estimating work: always factor in testing.
6 | * Testability is an attribute of good code. Code that cannot be tested is a problem.
7 | * Insufficient test coverage is better than no test coverage.
8 | * Prefer [Use Case Coverage over Code Coverage](https://kentcdodds.com/blog/how-to-know-what-to-test) (no need for 100% code coverage).
9 | * Additional history and guiding principles are in [this "manifesto" doc](https://docs.google.com/document/d/1XWx0GZLndtPF4-cwBeHii85osRj0ROPrflBF3DAVewA/edit)
10 |
11 | ## Best Practices & Standardization
12 |
13 | ### General
14 | * Organization of testing scripts in `package.json` ([more details](../package-json-script-names.md))
15 | * `npm run test`: Runs all test runners (Jest and/or Cypress)
16 | * `npm run test:watch`: Runs all test runners in watch mode
17 | * `npm run test:jest`: Runs Jest and exits
18 | * `npm run test:jest:watch`: Runs Jest in watch mode
19 | * `npm run test:cypress`: Runs Cypress and exits
20 | * `npm run test:cypress:open`: Open Cypress dashboard
21 |
22 | * [Apply the AHA principle](https://kentcdodds.com/blog/avoid-nesting-when-youre-testing). Try to minimize nesting, coupling and over-abstraction. These make tests brittle and hard to maintain.
23 |
24 | ### Jest
25 | * Unit test files for components should be siblings in the same directory with a `.test.js` suffix. Placing test code close to application code is intended to encourage testing and make it harder to forget.
26 | * For the test name, prefer the `it('should do something')` syntax because it is more self-documenting and intuitive
27 | * Use `describe()` and `beforeEach` sparingly. They lead to nesting and coupling.
28 |
29 | ### Testing Library
30 | * Prefer the `getByRole` query over others because it typically best matches the user's experience. [1](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-byrole-most-of-the-time)
31 | * Avoid `getByTestId` because it _least_ matches the user's experience.
32 | * We encourage using the `screen` object exported by Testing Library because the resulting idioms will be more similar in React and Vanilla JS projects. [1](https://testing-library.com/docs/queries/about#screen), [2](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-screen).
33 |
34 | ## Favorite Tools
35 | * Unit/integration testing: Jest + Testing Library
36 | * E2E testing: Cypress
37 |
38 | ## Resources
39 | * [Common Testing Library mistakes](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)
40 | * [Avoid Nesting](https://kentcdodds.com/blog/avoid-nesting-when-youre-testing)
41 |
--------------------------------------------------------------------------------
/til/README.md:
--------------------------------------------------------------------------------
1 | # TIL
2 |
3 | "Today I learned" or "thing I learned". Roughly-organized quick MD notes about stuff we encounter.
4 |
--------------------------------------------------------------------------------
/til/css/filters-and-transitions.md:
--------------------------------------------------------------------------------
1 | Today I learned a bit about CSS `filter`, which is a *property* that allows you to do a bunch of annoying things, but I find that the `grayscale` filter value is not terrible. I played around in a [codepen](http://codepen.io/lyzadanger/pen/vEpxMy) and noted:
2 |
3 | * You can transition on `filter`, at least in some browsers
4 | * You can listen for `transitionend` just like with any transition
5 | * `grayscale` can take a percentage argument which operates something like the "opacity" of the filter, e.g. `grayscale(50%)`
6 |
7 | I do not however know the performance impacts of filters and those transitions and anticipate they could be significant issues.
8 |
9 | ## Events
10 |
11 | `transitionend` events are useful but supported inconsistently, no surprise there. [Bootstrap's transition.js](https://github.com/twbs/bootstrap/blob/master/js/transition.js) does a decent job of wrapping that up. I adapted a slightly boiled-down variant of this for my own use. Intriguingly the feature test involves checking for a `style` property on a given element.
12 |
--------------------------------------------------------------------------------
/til/git/README.md:
--------------------------------------------------------------------------------
1 | ## Linking to Multiple Lines
2 |
3 | I learned today that you can link to a multiple-line selection, not just a single line, e.g. https://github.com/hexojs/hexo/blob/master/lib/plugins/console/generate.js#L89-L101
4 |
5 | Add `CONTRIBUTING.md` at the top of your repo and it will get linked to with a "read the guidelines for contributing..." automatically!
6 |
7 | ## --ours vs. --theirs
8 |
9 | Recently I learned about
10 |
11 | `git checkout --ours [file...]`
12 |
13 | and
14 |
15 | `git checkout --theirs [file...]`
16 |
17 | Which is a quick way to resolve a conflict on something in an intuitive way. Then commit the results.
18 |
19 | ## git rev-parse
20 |
21 | The [`git rev-parse` command](http://git-scm.com/docs/git-rev-parse) is a "porcelainish" interface to some lower-level git internals.
22 |
23 | Kinda handy:
24 |
25 | * `git rev-parse --is-inside-work-tree` returns a Boolean as to whether you are, well, currently inside of a working git tree
26 | * `git rev-parse --short HEAD` Gits you the short SHA hash for the most recent commit on HEAD
27 | * `git rev-parse --verify --short refs/stash` will return the short hash of the latest stash. Note that it will fail/exit 1 if there isn't a stash: `fatal: Needed a single revision` and thus needs to be handled appropriately if you're doing something meaningful with the response.
28 |
29 |
30 | ## git symbolic-ref
31 |
32 | `git symbolic-ref --quiet --short HEAD` is a programattic way to ask what your working branch is at the moment.
33 |
34 | ## Delete merged local branches
35 |
36 | ```
37 | git checkout master
38 | git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
39 | ```
40 |
41 | [Via this gist](https://gist.github.com/JoshuaEstes/2627607#delete-all-branches-that-have-been-merged)
42 |
--------------------------------------------------------------------------------
/til/js/README.md:
--------------------------------------------------------------------------------
1 | ## 2015-02-25
2 |
3 | Neat little trick that'll work in IE9+:
4 |
5 | ```javascript
6 | var print = console.log.bind(console, '>');
7 | print('Hello, World'); // > Hello, World
8 | ```
9 |
--------------------------------------------------------------------------------
/til/lyza/README.md:
--------------------------------------------------------------------------------
1 | # Trivial Things I learned
2 |
3 | (Not worthy of putting in conceptual TIL files).
4 |
5 | * 2015-02-19: How to go to the last line of a file in `vi`. You may start your snickering now. `:$`
6 |
--------------------------------------------------------------------------------