Paint

Paint is a collection of SCSS functions, mixins, placeholders and global styles that help us bootstrap our internal apps.

It also acts as an abstraction layer, keeping other frameworks / dependencies away from the applications. This makes structural changes (like removing a dependency or adding a new one) easier to implement.


Setup

Paint comes as a bower package (paint) and an npm package (as-paint).

To use the bower package, run bower install paint --save-dev.
For npm, run npm install as-paint --save-dev.

This is going to install all dependencies.

There are 2 ways to import paint into an application:

  • Out-of-the-box, without any theming / resets.
    For that, just @import '/bower_components/paint/styles/paint' or @import '/node_modules/paint/styles/paint'

  • Allow theming and customising components. In this case, you need to load some components individually and create an app-specific paint-settings file (which will act as your theme file):

/// Paint Core
@import '/bower_components/paint/styles/core';

/// Application-specific Resets
@import 'paint-settings';

/// Import Paint Global Settings
@import '/bower_components/paint/styles/settings';

/// Paint Tools / Helpers
@import '/bower_components/paint/styles/tools';

/// Import Global Components
@import '/bower_components/paint/styles/global';

/// Import all Paint Components
@import '/bower_components/paint/styles/components';

To make any future changes easier, add all of the above in a paint-loader.scss file and import it in your main application stylesheet, before the app-specific dependencies and styles, e.g

/// application.scss
@import 'paint-loader';
@import 'styles';

/// paint-loader.scss
@import '/bower_components/paint/styles/core';
@import 'paint-settings';
@import '/bower_components/paint/styles/settings';
@import '/bower_components/paint/styles/tools';
@import '/bower_components/paint/styles/global';
@import '/bower_components/paint/styles/components';

/// styles.scss
@import 'components/custom-component1';
@import 'components/custom-component2';
...

Structure

Paint is separated into

  • Core
  • Settings
  • Tools
  • Globals
  • Components

Core

This contains a set of functions and mixins that are mandatory for the rest of the paint components to work properly. It includes:

- core/dependencies
  normalize-scss
  bourbon
- core/functions
  export
  map
  bound
- core/resets

Settings

This contains variables that are shared between globals, tools and components. Settings use the core functions, that's the reason why we need to load Core before.

Tools

A set of reusable styles that we want to share between the components and throughout the application.

- tools/functions
  color
- tools/mixins
  detached-border
  overlay
  bem
- tools/placeholders
  vertical-align

Global

This contains the most basic set of components.
Each component might have extra package dependencies that are not defined above.

- global/components
  icon
    font-awesome
  button
  grid
    neat (bower) / node-neat (npm)
  typography

Components

A set of components that are pretty common in all applications

- layout
- navigation
- label
- panel
- flip-panel
- side-panel
- tab
- table
- notification
- progress-bar
- form
- quick-jump
- modal
- dropdown
- step

Deprecation warning
Most of these components are going to be extracted into separate repos and refactored to make it easier to customise and more flexible to extend.


How to use Paint

[upcoming]


Customising Component Settings

[upcoming]


Usage Guidelines

Most coding style issues are taken care of automatically by the linter. There are though some things that are difficult to implement/not yet implemented in the linter and you should check manually.

[upcoming]


Contributing

We use git flow to manage feature/hotfixes/releases. The easiest setup is to clone the repository, then run:

cd paint
git branch master origin/master
git flow init -d
git flow feature start <your initials>/<feature name>

Then, do the work and commit your changes.

git flow feature publish <your initials>/<feature name>

When done, open a pull request for your feature branch. Make sure you branched-off develop not master.

Publishing process (internal)

  • After the review, merge to develop, then create a new release (vX.xx.xx).

  • Bump Paint version (bower / npm) bower patch && npm patch.
    Npm might return an error, since the tag name might already exist. No worries, all good.

  • Push changes and tags

  • Finish the release, adding the release notes to the description:

## Changelog

* Feature
* Feature
...
  • Run npm publish on master.

  • Generate Documentation:

npm install -g sassdoc
npm install -g sassdocify
// run the above only the first time you do this

bin/docs

This is going to push documentation to a gh-pages branch that automatically updates http://alphasights.github.io/paint/

If the changes you made affect any ember-cli-paint component you also need to:

  • Update paint's version in ember-cli-paint index.js and bower.json
  • Release a new version of ember-cli-paint
    • npm version major | minor | patch
    • npm publish

Dropdowns

Labels

variables

label-default-settings

Since v0.8.27
$label-default-settings: (
  padding: 5px 10px,

  styles: (
    base: color(border),
    primary: color(primary),
    secondary: color(secondary),
    alert: color(alert),
    error: color(alert),
    warning: color(warning),
    success: color(success),
    info: color(info)
  ),

  sizes: (
    tiny: .6,
    small: .8,
    base-size: 1,
    large: 1.2
  )
);

Description

Default settings

Example

span.default-label {
  @extend %label-base;
}

span.primary-tiny {
  @extend %label-primary;
  @extend %label-tiny;
}

span.info-base {
  @extend %label-info;
  @extend %label-base-size;
}

h1 > span.label {
  @extend %label-base;
  @extend %label-large;
}

mixins

[private] label-style

Since v0.8.27
@mixin label-style() { ... }

Description

Generates background color and text color

Parameters

None.

Used by

[private] label-size

Since v0.8.27
@mixin label-size() { ... }

Description

Generates font size from label settings

Parameters

None.

Used by

[private] label-placeholders

Since v0.8.27
@mixin label-placeholders() { ... }

Description

Generates label style and size placeholders

Parameters

None.

Requires

placeholders

[private] label

Since v0.8.27
%label { ... }

Description

Basic label styles

Used by

label-ellipsis

Since v0.8.27
%label-ellipsis { ... }

Description

Label modifier - ellipsis. Extend to enable text-ellipsis when having long text items

Layout

variables

layout-default-settings

Since v0.8.29
$layout-default-settings: (
  selectors: (
    main: '.application',
    content-wrapper: 'main',
    content: '> .content'
  )
);

Description

Default settings

layout

Since v0.8.29
$layout: () !default;

Description

Global application layout styles

Example

Usage

<body>
  <div class="application">
    <div class="main-navigation">
       // ...
    </div>

    <main>
      <div class="content">
        //...
      </div>
    </main>
  </div>
</body>

Modals

Navigation

Panels

variables

flip-panel-default-settings

Since v0.8.43
$flip-panel-default-settings: (
  header-height: panel-settings(header-height),
  footer-height: panel-settings(footer-height),
  icons: (
    back: long-arrow-left,
    forward: long-arrow-right
  ),
  transition-settings: .3s ease-in-out
);

Example

Usage

.flip-panel {
  @include flip-panel;
}

Default Markup

<div class="flip-panel [flipped]">
  <div class="front">
    <header>
      <h1>Flip Panel Front</h1>
    </header>

    <div class="content">
      <section>
        Flip panel front section content
      </section>
    </div>

    <footer>
      <span><a>More information</a></span>
    </footer>
  </div> <!-- .front -->

  <div class="back">
    <header>
      <h1><a><i class="back-icon"></i> Back to Front</a></h1>
    </header>

    <div class="content">
      <section>
        <p>Flip panel back content</p>
      </section>
    </div>
  </div> <!-- .back -->
</div>

Custom panel style and back face with footer

Pass option `$with-footer: true` to `flip-panel`. It is advised to specify a min-height for the panel as well.

Usage

.custom-flip-panel {
  @include flip-panel(primary, $with-back-footer: true, $min-height: 400px);
}

Animation

Toggle class `.flipped` on the main selector to trigger the flipping animation

panel-default-settings

Since v0.8.43
$panel-default-settings: (
  header-height: $h1-font-size + $column-gutter,
  footer-height: $h1-font-size + $column-gutter / 2,
  styles: (
    default: color(border, light),
    primary: color(primary),
    link: color(link),
    success: color(success),
    warning: color(warning),
    alert: color(alert),
    info: color(info, light)
  ),
);

Example

Usage

.custom-panel-widget {
  @extend %panel-widget;
}

Custom Panel Styles

// paint-settings.scss
$panel: (
  styles: (
    success: color(success, dark),
    info: color(info)
  )
);

// Custom stylesheet
.fancy-green-panel {
  @extend %panel-success;
}

mixins

[private] flip-panel-icons

Since v0.8.43
@mixin flip-panel-icons() { ... }

Description

Generate icons used for the panel header

Parameters

None.

[private] flip-panel-scroll-content

Since v0.8.43
@mixin flip-panel-scroll-content($with-header: true, $with-footer: false) { ... }

Description

Create the scrollable content block based on the presence of header and footer

Parameters

parameterNameparameterDescriptionparameterTypeparameterDefault value
$with-header

Specify if the panel has a header

Booleantrue
$with-footer

Specify if the panel has a footer

Booleanfalse

Used by

flip-panel

Since v0.8.43
@mixin flip-panel($with-front-header: true, $with-front-footer: true, $with-back-header: true, $with-back-footer: false, $min-height: false) { ... }

Description

Mixin that generates the flip-panel styles

Parameters

parameterNameparameterDescriptionparameterTypeparameterDefault value
$with-front-header

Specify if the panel front has a header

Booleantrue
$with-front-footer

Specify if the panel front has a footer

Booleantrue
$with-back-header

Specify if the panel back has a header

Booleantrue
$with-back-footer

Specify if the panel back has a footer

Booleanfalse
$min-height

Specify a fixed height for the panel

Valuefalse

Requires

[private] panel-background

Since v0.8.43
@mixin panel-background($background-color: color(border, light)) { ... }

Description

Panel header background

Parameters

parameterNameparameterDescriptionparameterTypeparameterDefault value
$background-color

Sets the panel header background to a gradient and sets the text color dynamically based on the color brightness.

Colorcolor(border, light)

Used by

[private] panel-placeholders

Since v0.8.43
@mixin panel-placeholders($styles: panel-settings(styles)) { ... }

Description

Generates all panel variation placeholders defined in the settings

Parameters

parameterNameparameterDescriptionparameterTypeparameterDefault value
$styles

The style variations map

Mappanel-settings(styles)

Requires

placeholders

panel

Since v0.8.43
%panel { ... }

Description

The placeholder that holds the base panel styles

Used by

Progress Bars

variables

progress-bar-default-settings

Since v0.8.34
$progress-bar-default-settings: (
  background-color: color(border, light),
  border: 0,
  border-radius: $global-radius / 2,
  padding: 0,
  meter: (
    selector: '> div'
  ),

  styles: (
    base: color(success, light),
    primary: color(primary),
    secondary: color(secondary),
    alert: color(alert),
    error: color(alert),
    warning: color(warning),
    success: color(success),
    info: color(info)
  ),

  sizes: (
    small: 1px,
    base-size: 3px,
    large: 10px
  )
);

Description

Default settings, styles and sizes

Example

Basic usage

// Default classes
.progress-bar {
  @extend %progress-bar-base;
}

// Custom usage
.project-progress-bar {
  @extend %progress-bar-[base, primary, secondary, alert ...] ;
  @extend %progress-bar-[small, base-size, large];
}

Basic markup

<div class="project-progress-bar">
  <div style="width: 30%"></div>
</div>

mixins

[private] progress-bar-style

Since v0.8.34
@mixin progress-bar-style() { ... }

Description

Generates background color

Parameters

None.

Used by

[private] progress-bar-height

Since v0.8.34
@mixin progress-bar-height() { ... }

Description

Generates bar height from settings

Parameters

None.

Used by

[private] progress-bar-placeholders

Since v0.8.34
@mixin progress-bar-placeholders() { ... }

Description

Generates progress-bar style and size placeholders

Parameters

None.

Requires

Steps

variables

step-default-settings

Since v0.8.33
$step-default-settings: (
  height: $button-small-height,

  colors: (
    inactive-background: color(border, light),
    inactive-border: color(border),
    inactive-count: color(border),
    highlighted-background: color(info, light),
    highlighted-border: color(gray),
    highlighted-count: color(gray),
    active-background: color(primary, light),
    active-border: color(primary),
    active-count: color(primary, dark),
  ),

  selectors: (
    highlighted: '.highlighted',
    active: '.active'
  )
);

Example

Steps with border and icons

<ol class="steps with-border with-icons">
  <li><a>First Step</a></li>
  <li class="highlighted"><a>Second Step</a></li>
  <li class="active"><span>Current</span></li>
  <li><span>Inactive</span></li>
  <li><span>Inactive</span></li>
  <li><span>Inactive</span></li>
</ol>

Steps with border and counts

<ol class="steps with-border with-counts">
  <li class="highlighted with-pre"><span>10</span><a>First Item</a></li>
  <li class="highlighted with-pre"><span>8</span><a>Second Item</a></li>
  <li class="active"><span>Current</span></li>
  <li class="with-post"><span>Inactive Item</span><span>0</span></li>
  <li class="with-post"><span>Inactive Item</span><span>0</span></li>
  <li><span>Inactive</span></li>
</ol>

Custom steps

.basic-breadbrumb,
.border-steps,
.icon-steps {
  @extend %steps;
}

.icon-steps {
  @extend %steps-with-icons;
}

.border-steps {
  @extend %steps-with-border;
}

placeholders

steps

Since v0.8.33
%steps { ... }

Description

Default steps placeholder, acts like a breadcrumb

Used by

steps-with-icons

Since v0.8.33
%steps-with-icons { ... }

Description

Steps extention placeholder, allows use of icons

Requires

steps-with-border

Since v0.8.33
%steps-with-border { ... }

Description

Steps extention placeholder, adds a border around elements

Requires

Used by

steps-with-counts

Since v0.8.33
%steps-with-counts { ... }

Description

Steps extention placeholder, allows adding pre or post content

Requires

Tabs

variables

tab-default-settings

Since v0.8.18
$tab-default-settings: (
  active-class: '.active',
  active-tab-selector: a,
  background-color: color(white),
  border-color: color(border),
  border-color-active: color(link),
  border-height: 3px,
  height: 60px,
  text-color: color(text, small),
  text-color-active: color(text),
  text-size: $h4-font-size,
  padding: 0 $column-gutter / 2,
  margin: 0 $column-gutter / 2,
  transition-duration: $global-transition-duration / 2
);

Example

Usage

.my-tabs {
  @include tabs;
}

Default Markup

<section class="tabs">
  <nav>
    <ul>
      <li><a>First Tab</a></li>
      <li><a class="active">Second Tab</a></li>
      <li><a>Third Tab</a></li>
    </ul>
  </nav>

  <div class="content">
    ...
  </div>
</section>

mixins

tabs

Since v0.8.18
@mixin tabs() { ... }

Description

Main tabs mixin, to be applied to the tabs wrapper

Parameters

None.

Requires

[private] tabs-nav

Since v0.8.18
@mixin tabs-nav() { ... }

Description

Tab Nav Group

Parameters

None.

Requires

Used by

[private] tab-item

Since v0.8.18
@mixin tab-item($active-selector: a) { ... }

Description

Tab Nav Item

Parameters

parameterNameparameterDescriptionparameterTypeparameterDefault value
$active-selector

Sets the active state selector, can be a or li

Valuea

Used by

placeholders

tabs

Since 0.9.15
%tabs { ... }

Description

Tabs placeholders

Example

BEM Structure

%tabs
  %tabs__nav

%tabs-nav
  %tabs-nav__item
    %tabs-nav__link

%tabs-nav--fluid-widths
%tabs-nav--fluid-widths__item

Usage

@include bem-block('custom-tabs') {
  @extend %tabs;

  @include bem-element('nav') {
    @extend %tabs__nav;
  }
}

@include bem-block('custom-tabs-nav') {
  @extend %tabs-nav;
  // @extend %tabs-nav--fluid-widths; // optional

  @include bem-element('item') {
    @extend %tabs-nav__item;
    // @extend %tabs-nav--fluid-widths__item; // optional
  }

  @include bem-element('link') {
    @extend %tabs-nav__link;
  }
}

Usage

<div class="newtabs">
  <nav class="custom-tabs__nav">
    <ul class="custom-tabs-nav">
      <li class="custom-tabs-nav__item"><a class="custom-tabs-nav__link" href="#">Item</a></li>
      <li class="custom-tabs-nav__item"><a class="custom-tabs-nav__link active" href="#">Item</a></li>
      <li class="custom-tabs-nav__item"><a class="custom-tabs-nav__link" href="#">Item</a></li>
    </ul>
  </nav>
</div>

tabs-nav

Since v0.8.18
%tabs-nav { ... }

Description

Block: tabs-nav Elements: item, link Modifiers: fluid-widths - affects item