Create a Compony-component

Uploading your component to the platform and making it public, doesn't mean it will be compatible for your future projects. Only components that are self-independent will be usable by others, or by yourself in future projects.

So how do we make a component self-independent?

Color agnostic CSS #

When downloading a component from someone else, you will get a black & white sketchbook, where you can define your own colors. Because If you would create a green component, and someone else comes along and plugs it in to their blue project, things are going to get out of hand really quickly.

This means that your color definitions should all become gray-values, before you commit them to the platform.

An example

Let's say we want to contribute below component on the platform:

my-component
dist
sass Created with Sketch.
my-component.scss

@import "sass-essentials";

.my-component {
  color: $blue;
}

YAML Created with Sketch.
libraries.yml

Then that would mean we would need to change all the colors to greyvalues like so:

sass Created with Sketch.
my-component.scss

@import "sass-essentials";

.my-component {
  color: #CCC;
}

NOTE: Please make sure that the different parts of your components have enough contrast when changing the colors to gray-values.

Font agnostic CSS #

When downloading a component from someone else, you don't want to use their fonts. Because otherwise that would mean that each component would require another font. And again, this would get out of hand quite quickly.

Therefor, please remove any CSS-declarations defined with:

  • font-family
  • font-weight
  • font-style

font-size

If your component has different font-sizes, it's considered ok to use the font-size declaration, as long as you keep it in rem and not hardcode it in px. Rem's will translate better across different fonts by default. Please use 1 rem as a default, and try to keep variations to a minimum.

@font-face

If you really want to add a font to a component, Creating a font-component is also a possibility! A font component would be the exception to this rule. Example component: the Montserrat font.

Variable free Sass #

Your component should work, without relying on variables defined in other components.

This means that your Sass can't rely on variables or mixins that are not defined in the component itself

Breakpoints

Using global breakpoints made a lot of sense, but it has become more of a common practice than a good practice.

An example: If component-a should break on 40rem and component-b should break on 42rem, then why would you define both breakpoints in the _global component?

We encourage component-based variables for breakpoints. (a component example: form-item--radiobuttons)

So your Sass could look like this:

sass Created with Sketch.
my-component.scss

@import "sass-essentials";

$bp-s: 30rem;
$bp-m: 50rem;

.label-text {
  position: relative;
  @media(min-width: $bp-s) {
    padding-right: 2rem;
  }
  @media(min-width: $bp-m) {
    padding-right: 4rem;
  }
}

Extending

Don't extend in Sass, it creates an anti-pattern in CSS, and it links components together in a way that's just not scalable. Read more about the anti-pattern of Sass extends.

Testing

An easy way to test this is to remove this:

@import 'sass-essentials';

on top of your sass file and see if Gulp can still compile the CSS.

Twig blocks #

Required block statement

In every template of a component that doesn't contain -- in it's name, there should be a before block statement, so templates that are extending can have a way of adding libraries.

Using block statements is heavily recommended (Docs: Twig-blocks)

Clear naming

Block statements follow a naming convention that is based upon the naming of the variable being printed inside. So if you are wrapping {{ content }} in a block, then the name of the block should be content as well.

No custom theme name #

The convention for components on the platform is that they are built for a theme that is named compony.

Function-names

So when writing functions inside your-component.theme file, please change the name of your custom theme to compony, before contributing a component.

So not this:

my-component.theme

function my_custom_theme_preprocess_my_component(&$variables, $hook) {
  // custom code
}

but this:

my-component.theme

function compony_preprocess_my_component(&$variables, $hook) {
  // custom code
}

Libraries

When attaching a library to a component, please make sure you link to the library with the compony theme name.

So not this:

Twig Created with Sketch.
my-component.html.twig

{% extends 'node.html.twig' %}

{% block before %}
  {{ attach_library('my-custom-theme/node--blog--teaser') }}
{% endblock %}

But this:

Twig Created with Sketch.
my-component.html.twig

{% extends 'node.html.twig' %}

{% block before %}
  {{ attach_library('compony/node--blog--teaser') }}
{% endblock %}

Use the default Gulp config #

Within your project you will have changed your gulpfile.js/project.config.js to suit your project.

Before you contribute your component, you should run gulp with the project.config.js containing the default settings. You can copy those settings from the documentation.

Components on the platform should have their dist folders included with them. Therefor, please remove the dist folder from your component, so Gulp can regenerate it, without containing too much stuff such as mapping files.