Coder Social home page Coder Social logo

mgechev / angular2-style-guide Goto Github PK

View Code? Open in Web Editor NEW
1.2K 104.0 98.0 253 KB

[Deprecated] Community-driven set of best practices and style guidelines for Angular 2 application development

Home Page: https://mgechev.github.io/angular2-style-guide/

angular best-practices deprecated

angular2-style-guide's Introduction

Deprecated

Angular 2 Style Guide

Official style guide

Together with the Angular core team and John Papa, we're working on an official style guide which incorporates all the best practices from:

  • Practices discovered during the internal usage of Angular 2 in Google.
  • The previous version of this style guide, which can be found here.
  • John Papa's AngularJS 1.x and Angular 2 style guides.

The previous version of the style guide can be found here.

The official style guide can be found here.

angular2-style-guide's People

Contributors

antonybudianto avatar at15 avatar buehler avatar deeleman avatar dzhavat avatar gitter-badger avatar joshwiens avatar lennonjesus avatar mgechev avatar modohash avatar mohammedzamakhan avatar nareshbhatia avatar ocombe avatar rossjhagan avatar rvanlaarhoven avatar sbley avatar unnoted avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

angular2-style-guide's Issues

Inconsistent model file naming in directory structure example

The guide mentions that models should not have a suffix:

Name the files which contain component, directives, pipes and services definition with the corresponding suffix.

// Contains the "home-dashboard" component
home-dashboard.component.ts

// Contains the ShoppingCart model. Notice that there is no suffix for the models.
shopping-cart.ts

// Contains the logic for the "checkout" service.
checkout.service.ts

But the directory structure example has the following examples with a .model suffix: admin.model.ts, shopping-cart.model.ts, shopping-item.model.ts.

The .model suffix should be removed.

consider using GitBook

In my experience, creating these super huge Readme files will go south sooner or later... hard to maintain, hard to refactor etc...

Consider using GitBook, all in all Dan Abramov Redux guide is really good example how things should look like IMHO.

thx

Where to put application interfaces?

In Tour of Heroes, class HeroDetailComponent has a hero property which implement the Hero interface :

https://github.com/angular/angular.io/blob/7e86e9411bfbd4effbcc269f8965939d2cb29a69/public/docs/_examples/tutorial/ts/app/hero-detail.component.ts#L11

The tour puts the Hero interface in ./hero.ts. Some questions:

  • Every other filename in the tutorial encodes what kind of thing it is, e.g. app.component.ts. IMO, this filename should have been hero.interface.ts or as your guide says, "corresponding suffix".
  • In theory, interfaces are distinct from implementation. Many tutorials so far, though, just use interfaces in type declarations, not in class statements. Still, should the file with the interface be in the "bounded context"?
  • Based on your "single reason to change" (single responsibility principle), should each interface be in a separate file, with only the interface in the file? Should it be a default export or a named export?

Simplify directory structure

I know the discussion about the directory structure was a lengthy one, but I was wondering what you thought about simplifying it. The recommended structure seems a bit verbose, including a prefix that could be removed from each file and instead be used to create a containing directory, as well as a repetitive "component" segment that seems unnecessary for non-TS files. An alternative to the current directory structure might look something like the following:

|- admin
|   |- home-dashboard
|   |   |- component.ts
|   |   |- styles.css
|   |   |- template.html
|   |- login
|   |   |- component.ts
|   |- models
|   |   |- admin.ts
|   |- services
|   |   |- order-management.ts
|   |   |- user-management.ts
|- shared
|   |- avatar
|   |   |- component.ts
|   |   |- template.html
|   |- directives
|   |   |- form-validator.ts
|   |   |- tooltip.ts
|   |- login-form
|   |   |- component.ts
|   |   |- styles.css
|   |   |- template.html
|   |- pipes
|   |   |- format-order-name.ts
|   |- services
|   |   |- authorization.ts
|- shop
|   |- edit-profile
|   |   |- component.ts
|   |   |- styles.css
|   |   |- template.html
|   |- home
|   |   |- component.ts
|   |   |- template.html
|   |- models
|   |   |- shopping-cart.ts
|   |   |- shopping-item.ts
|   |   |- user.ts
|   |- register
|   |   |- component.ts
|   |- services
|   |   |- checkout.ts

question: html within template or html-files

Hello mgechev,

i really love your style guide. Especially the part about the inputs and hostbindings within the component. But I'm a little bit curios since your directory structure suggests to have html files, while in the template part you say "Keep the components' templates as lean as possible and inline them inside of the @Component decorator". Did i miss something?

Naming Pipes' controllers

Perhaps a bit too anal after the discussion held at #4 but in order to leave no room for doubt, may be it would be worth to specify a convention for Pipes controller classes as well.

Currently the framework itself defines the builtin pipes modules with a combination of name plus the Pipe suffix. It seems logical to follow the same convention and state it somewhere in the guide if everybody's fine with it.

Style for Array

Maybe add a style for array?

names: string[];
levels: Level[];
interface User {
  emails: {
    address: string,
    verified: boolean
  }[]
}

or

names: Array<string>;
levels: Array<Level>;
interface User {
  emails: Array<{
    address: string,
    verified: boolean
  }>
}

Feature: Style Guide Snippets

Issue for tracking the creation of snippets for popular editors based on the recommendations in the guide.

List of planned snippets will grow as their styling recommendations are solidified.

Supported Editors

Planned JS / TS Snippets

  • Components
  • Directives
  • Pipes
  • Services
  • RouteConfig
  • Route
  • Test

Planned HTML Snippets

  • ngFor
  • ngIF
  • ngSwitch
  • ngSwitchWhen
  • ngSwitchDefault
  • ngClass
  • ngModel
  • ngForm

Completion Categories

  • Annotations
  • Decorators
  • Lifecycle
  • Routing
  • Directives
  • Attributes
  • Pipes

Style for *ngFor

I saw several kinds of codes online, they are all working well, but I am not sure which style is recommended.

These are three of them:

*ngFor="#alert of alerts #i = index #l = last"
*ngFor="#alert of alerts; #i = index, #l = last"
*ngFor="#alert of alerts; #i = index; #l = last"

Maybe add one style guide for this? Thanks

awesome....

love the article... looking forward for more advanced topics. please expand on detachment of elements

Remove or change section on reusable libraries

The current section has a broken link to the angular2 cli library publishing guide. Even when it wasn't broken, this guide had some ideas that seemed a bit premature and maybe not well thought out. It would be best to leave this out until things stabilize.

Avoid using forwardRef considerations

I didn't find aby mentions of this rule in official styleguide.

https://angular.io/styleguide

There are some cases where we need forwardRef:

  1. Resolve cycle dependencies. I know, I know you tell me it's a bad design, but sometimes we do have them. For example when rendering tree structure of similar components (A renders B, B renders A etc.). It's a valid scenario and cannot be ignored.
  2. ngModel implementation. It's probably just because I didn't find a better way to implement this. Imagine you need implement custom input component that supports ngModel property (e.g. <my-input [(ngModel)]="value" >) To achieve this we need two things:
  3. Implement ControlValueAccessor for our component,
  4. Create custom Control Value Accessor like
export const CSN_MY_INPUT_CONTROL_VALUE_ACCESSOR = new Provider(
    NG_VALUE_ACCESSOR, {
        useExisting: forwardRef(() => MyInputComponent),
        multi: true
    }
);

Supporting ESLint as an "or" option to JSCS / JSHint

I've recently converted over to ESLint from the standard jscs / jshint mainly for the pluggable nature of it.

Would you consider a PR for a standard ESLint configuration?

Also, I was going to create .rc files for for jscs, jshint, tslint to go along with snippets once the style has settles enough to do so.

  • Add ESLint configuration
  • Move linting configurations into .rc files
  • Move rules explanation into Linting.MD and link to README.md

Variable, property namings

Hey @mgechev

Awesome job!

I'd consider a word or two about the general variable namings. Since TypeScript is strongly influenced by C# and uses many of it's principles, I'd suggest the following things:

  • public variables are named camelCase without a leading _

Why? They are accessible like functions or properties, so they should inherit the same naming structure.

  • private variables should be named _camelCase with a leading _

Why? Because they are private and should not be accessible from outside the class. In addition to that, when properties are used, the variable cannot have the same name as the property.

class MyClass {
    private _onlyForMyClass:number = 42;
    private _leet:number = 1337;
    public foo:string = 'bar';

    public get leet():number {
        return this._leet;
    }

    //and a possible setter
    public set leet(value:number){
        this._leet = value;
    }
}

What are your thoughts?

Cheers
Chris

Drop models

Introduction

Currently we have the following entity types:

  • components
  • directives
  • pipes
  • services
  • models

Problem

This does not completely align to the concepts defined by Angular 2, since the framework doesn't include models.

Although it is typical scenario to have entities which represent the domain, in some architectures such as flux and redux having models is optional. In these architectures we have Stores, Actions, Dispatchers, Components, Reducers, etc. but we do not have recommendations on how we should present the business model and/or communicate with services.

The style guide aims to be agnostic in terms of language (we have separate sections for this) and micro-architecture.

Proposal

My suggestion is to drop the models entity from the style guide since this way we are implicitly implying usage of MV* approach.

// cc @evanplaice @nareshbhatia @d3viant0ne @ludohenin

Discuss about directory structure to share code between projects

How is the best practice to share code between projects?

Below dashboard example should be use components of the eye project, and nose project.

In this case, I run three commands to see all aplications , but, I need copy nose source and eye source to dashboard project to share componets

npm run serve.dev -- --client eye
npm run serve.dev -- --client nose
npm run serve.dev -- --client dashboard


src
├── eye
│   ├── app
│   │   ├── components
│   │   │   ├── eye.component.html
│   │   │   ├── eye.component.ts
│   │   │   ├── eye.component.css
├── nose
│   ├── app
│   │   ├── components
│   │   │   ├── nose.component.html
│   │   │   ├── nose.component.ts
│   │   │   ├── nose.component.css
├── dashboard
│   ├── app
│   │   ├── components
│   │   │   ├── dashboard.component.html
│   │   │   ├── dashboard.component.ts
│   │   │   ├── dashboard.component.css

API design

The (hopefully) Definitive Angular2 API Design Style Guide

Say what you want about OOP and the dangers of deep coupling and over-use of inheritance. One thing that OOP does really well is encapsulation.

Hiding the internal implementations had 2 significant benefits:

  • it makes code easier for users to reason about
  • it allows developers to change the internal structure without negatively impacting users

API breaking changes can be devastating to the long-term stability of a project. The ES6 module provides a solid foundation. The facade pattern provides the means to define a convention that will benefit both users and developers alike. So, what is the facade pattern?

The facade pattern (or façade pattern) is a software design pattern commonly used with object-oriented programming. The name is by analogy to an architectural facade. A facade is an object that provides a simplified interface to a larger body of code, such as a class library.

Source: Facade Pattern - Wikipedia

To see the full benefit, we need a reasonably complex application structure.

.
├── app
│   ├── about
│   │   └── components
│   │       ├── about.e2e.ts
│   │       ├── about.component.ts
│   │       └── about.spec.ts
│   ├── master
│   │   └── components
│   │       ├── master.css
│   │       ├── master.e2e.ts
│   │       ├── master.view.html
│   │       ├── master.component.ts
│   │       └── master.spec.ts
│   ├── assets
│   │   ├── img
│   │   │   └── smile.png
│   │   └── main.css
│   ├── home
│   │   └── components
│   │       ├── home.css
│   │       ├── home.component.ts
│   │       └── home.spec.ts
│   ├── shared
│   │   └── services
│   │       ├── name_list.service.ts
│   │       └── name_list.spec.ts
│   ├── todo
│   │   ├── components
│   │   │   ├── todo.view.html
│   │   │   ├── todo.component.ts
│   │   │   ├── todoitem.component.ts
│   │   │   ├── todoitem.view.html
│   │   │   ├── todoitem.e2e.ts
│   │   │   ├── todolist.component.ts
│   │   │   ├── todolist.view.htm
│   │   │   └── todolist.e2e.ts
│   │   ├── models
│   │   │   └── todos.model.ts
│   │   ├── services
│   │   │   └── todo.service.ts  
│   │   └── todo.ts <- module facade
│   ├── main.component.ts
│   └── index.html
└── package.json

What we have here is a basic website with a reasonably complex Todo feature. Lets say we want to import the TodoComponent for use in the HomeComponent.


Use Case 1: The Basics

The nested folder structure makes the import statements look pretty hairy.

  1. Setup the TodoService so it's available for injection

    app/main.ts

    import { TodoService } from './todo/services/todo.service' // <- deep link ಠ_ಠ
    ...
    bootstrap(MainComponent, [ TodoService ]);
  2. Import the TodoComponent

    app/home/components/home.ts

    import { TodoComponent } from '../../todo/components/todo.component'; // <- deep link ಠ_ಠ
    ...

Not bad but there's room for improvement if we implement the facade.

/app/todo/todo.ts

export { TodoComponent } from './todo/todo.component';
export { TodoService } from './todo/todo.service';

Then the setup becomes

  1. Setup the TodoService so it's available for injection

    app/main.ts

    import { TodoService } from './todo/todo' // <- shallow link ʘ‿ʘ
    bootstrap(MainComponent, [ TodoService ]);
  2. Import the TodoComponent

    app/home/components/home.ts

    import { TodoComponent } from '../../todo/todo'; // <- shallow link ʘ‿ʘ

OK, I admit. This example is pretty contrived but it sets up a good foundation that we'll build from.

Usefulness Factor: 3/10


Use Case 2: Maintainability

So we've got a facade, and both the service and component linked to it. Throwing all of the components into the module seems a bit messy. Looks like a good time to add another level of directories and split the files up by context.

│   ├── todo
│   │   ├── todo
│   │   │   ├── todo.view.html
│   │   │   └── todo.component.ts
│   │   ├── todoitem
│   │   │   ├── todoitem.component.ts
│   │   │   ├── todoitem.view.html
│   │   │   └── todoitem.e2e.ts
│   │   ├── todolist
│   │   │   ├── todolist.component.ts
│   │   │   ├── todolist.view.htm
│   │   │   └── todolist.e2e.ts
│   │   ├── models
│   │   │   └── todos.model.ts
│   │   ├── services
│   │   │   └── todo.service.ts  
│   │   └── todo.ts <- module facade

Since all of the parts that are referenced externally already point to the facade, all we have to do now is update the facade to reflect the change.

/app/todo/todo.ts

export { TodoComponent } from './todo/todo.component'; // <- was './components/todo.component';
export { TodoService } from './services/todo.service';

The links between the source files within the Todo feature still have to be updated but all changes are localized to the feature. As long as the rest of the app imports from the facade, the rest of the app shouldn't be affected. No more project-wide 'find in files'. No more stress about possibly missing a reference that needs to be updated and breaking the app.

The stability and maintainability characteristics are warming up.

Usefulness Factor: 6/10


Use Case 3: Reuse

Maintainability is cool and all but what if we'd like to reuse this feature on another site, put it under its own source control, and post it on GitHub for some OSS cred?

The hard part is already done. A public API has been defined via the facade. All of the relevant components, services, models, etc are already organized as a single unit. The rest depend on personal preference.

I suggest:

  • initialize a new repo
  • copy the contents of the Todo feature directory
  • push to Github
  • install via NPM/JSPM

Assuming the module is mapped to todo using your ES6 module loader...

  1. Update the TodoService reference so it's available for injection

    app/main.ts

    import { TodoService } from 'todo' // <-- was './todo/todo
    bootstrap(MainComponent, [ TodoService ]);
  2. Import the TodoComponent

    app/home/components/home.ts

    import { TodoComponent } from '../../todo/todo'; // <- was '../../todo/todo'

Bonus: Before you extract the code from the project, try moving it to the shared folder and update the references. This is a good idea to check for references that weren't updated to point to the facade.

Now that the code is on GitHub. It can be developed independently, contributed to by others, and used on as many applications as desired.

Usefulness Factor: 10/10


Use Case 4: Composibilty

A facade is provided to localize the impact of changes to the feature. The feature has been restructured, allowing for growth. The feature has been extracted for reuse.

All of which is great if you're looking for a cookie-cutter implementation of the Todo feature. What about customizability? What happens when the feature needs to be integrated into an existing site?

For example your company wants to embed the Todo feature directly into an internal project tracking application. This will require application-specific styling and a new service to tie into the existing backend API.

One option is to create a new repo and copy the contents over. What about DRY? What about the benefits of the additional development that takes place on the original repo?

To enable a finer degree of granularity, the facade will need to be extended to update the public API.

/app/todo/todo.ts

export { TodoComponent } from './todo/todo.component';
export { TodoItemComponent } from './todoitem/todoitem.component';
export { TodoListComponent  } from './todolist/todolist.component';
export { TodosModel } from './models/todos.model';
export { TodoService } from './services/todo.service';

Since all of the parts are available via the public API, the Todo feature can be installed as a dependency and its parts imported individually.

Just create a new application-specific Todo feature and import the parts from the original that can be reused. In this case the TodoComponent and TodoService will need to be created, the TodoModel TodoItem, and TodoListService can be reused.

Usefulness Factor: 11/10


None of these techniques are 'novel'. The ES6 module loader allows a degree of control over imports that didn't exist previously. The facade pattern is used extensively throughout the Angular2 source. All this guide provides is the means to effectively leverage both.

Discuss about directory structure

Hi @mgechev !
I just read your style guide, it's awesome ! I was wondering about directory structure.

you create a folder for each feature you have as following:

├── app
│   ├── about
│   │   └── components
│   │       ├── about.e2e.ts
│   │       ├── about.ts
│   │       └── about.spec.ts

You mention that if your folder grows to contains more than 7 files you create subfolders (components or services). it feels like it's grouped by type and not based on feature

I just tought to simply flatten the entire folder this way :

├── app
│   ├── about
│   │   └── about.e2e.ts
│   │   └── about.component.ts
│   │   └── about.service.ts
│   │   └──about.html (if you require the template)
│   │   └── about.css
│   │   └── about.spec.ts

In the case you have more than 10 files and the folder became difficult to read, I would suggest to create folders by sub-features

├── app
│   ├── todo
│   │   └── todo.e2e.ts
│   │   └── todo.component.ts
│   │   └── todo.service.ts
│   │   └── todo.html
│   │   ├── todoitem
│   │   │   └── todoitem.e2e.ts
│   │   │   └── todoitem.component.ts
│   │   │   └── todoitem.html
│   │   ├── todolist
│   │   │   └──todolist.e2e.ts
│   │   │   └── todolist.component.ts
│   │   │   └── todolist.html

What do you think about it ? I never worked on large-scale angular 2 application, only angular 1, so maybe I missed something.

pipes in directory structure under shared?

Shouldn't pipes be under shared in the directory structure? I can imagine some highly specific pipes belonging to a single component, or more general pipes that can be shared

Module naming convention

This guide says we should use this_case for module filenames opposed to the kebab-case convention (recommended by Papa John in his TourOfHeroes tutorial). I'm with Papa on this one, I find it more natural (also regular dashes are easier to type).

Suggest naming facade files 'index.ts' rather than 'feature.ts'

This allows the exports from a feature to be accessed by import {FeatureExport} from 'app/feature'; rather than import {FeatureExport} from 'app/feature/feature';

The Angular 2 source uses the similar patterns. As an alternative you could have the façade file for a feature as feature.ts located at the root of the app folder, as a sibling of the feature folder. This results in the same import syntax except that you have feature code bleeding out into the app folder. I personally prefer the index.ts option.

Naming components' and directives' controllers

Introduction

Currently the style guide states that they should be suffixed with Ctrl. Although this is correct it doesn't brings a lot of semantics.

Suggestion

My suggestion is to change it to the following:

  • CustomPrefix + BasicDescription + Dir or Cmp

For instance:

// ui.js

@Directive({
  selector: '[sc-tooltip]'
})
export class ScTooltipDir { ... }

Pros

By following this convention for the end user of the directive will be clear that:

  • The the imported code unit is a directive (by the Dir suffix).
  • The selector of the directive is sc-tooltip.
  • The type of the selector of the directive is an attribute.

Cons

I don't see any serious cons in the lack of Ctrl as suffix.

// cc @gdi2290 @ludohenin @NathanWalker @PascalPrecht

Simplify directory structure

If we have a directory for components why is it necessary to suffix every file with component?
Seems like a big duplication and doesnt add to understand the files.

The directory by itself describes the type of files residing within it.

Name events without prefix 'on'

I would suggest the following naming convention for events:

Name events without the prefix 'on'. Name your event handler methods with the prefix 'on' followed by the event name.

/* WRONG */
<my-voter (onVoted)="onVoted($event)"></my-voter>
/* CORRECT */
<my-voter (voted)="onVoted($event)"></my-voter>

Why?: This is to be consistent with built-in events like button clicks:

<button (click)="showDetails()">Show Details</button>

Why?: Angular allows for an alternative syntax on-*. If the event itself was prefixed with 'on' this would result in an on-onEvent binding expression.

/* CORRECT */
<my-voter (voted)="onVoted($event)"></my-voter>
<my-voter on-voted="onVoted($event)"></my-voter>

The recommended file/folder structure feels redundant and cluttered.

Example:
components/avatar.component.ts

If we are already in the components folder, we don't need to have component in the file name. We already know we are dealing with a component.

I propose the following, based on Ember's new 'pods' concept.

instead of:

├── admin
│   ├── home-dashboard.component.ts
│   ├── home-dashboard.component.html
│   ├── home-dashboard.component.css
│   ├── home-dashboard.component.spec.ts
│   ├── login.component.ts
│   ├── login.component.spec.ts
│   ├── admin.model.ts
│   ├── user-management.service.ts
│   └── order-management.service.ts

I think it should be this:

.
├── app
     ├── components
     │   ├── home
     │   │   ├── dashboard
     │   │   │   ├── component.ts
     │   │   │   ├── template.html
     │   │   │   ├── style.css
     │   │   │   ├── spec.ts
     │   ├── login
     │   │   ├── component.ts
     │   │   ├── style.css
     │   │   ├── spec.ts
     ├── models
     │   ├── admin.ts
     ├── services
        ├── user-management.ts
        └── order-management.ts

this structure allows for a couple things:

  • de-cluttered browsing of the angular app
    • with this structure, you can begin to make some assumptions about where files are, which would allow this sort of thing to be omitted, yeilding a quicker, more friendly development experience.
@Component({
  selector: 'path/to/and/name-of-component',
  moduleId: module.id,
  templateUrl: 'path/to/and/name-of-component/template.html',
  styleUrls: ['path/to/and/name-of-component/style.css'],
  directives: [ROUTER_DIRECTIVES]
})

** this @Component declaration could be entirely inferred based on structure, but this would require some additional changes to angular2 to be able to support implicit declaration.

Edits:

  • unit tests go with the components, per discussion with @hallister and @d3viant0ne

Suggestion: Add guides for component css styling to the styleguide

Was just thinking. In our project at work, we are playing with how to name components and how to use/name the css classes.

We were using ITCSS as a base for our css structure Kinda like BEM, SMACSS combined with some extra goodies.
It helps a lot with the lexical scope and stuff.
But when you're building components, your lexical scope is mostly gone and instead of using BEM classes to define your HTML structure you can use your component names (HTML elements) to define structure/make the HTML more readable.

But you're probably still gonna use global styles combined with component styles on your component, therefore it would be nice to see the difference between the two at once.

We thought this could be a nice solution:

Old bem style:

<div class="sd-card">
  // .blue is a global class
  <div class="sd-card__header sd-card__header--big  blue">
         header text
  </div>
  <div class="sd-card__content sd-card__content--wide>
     lorem ipsum
  </div>
</div>

Component style

<sd-card>
  <sd-card-header class="--big blue">
      header text
  </sd-card-header>
  <sd-card-content class="--wide">
    lorem ipsum
  </sd-card-content>
</sd-card>

So defining component style classes with a double dash prefix like: --wide. Since they are usually modifiers of the style of the component

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.