Chasing The Dream of Style Guide Driven Development
One tiny css change causes a regression deep in the outer reaches of your site
(and, it goes unnoticed for lord knows how long)
Base Themes
{%
set classes = [
'block',
'block-' ~ configuration.provider|clean_class,
'block-' ~ plugin_id|clean_class,
]
%}
< div {{ attributes.addClass(classes) }}>
(From block.html.twig)
{% if attributes.hasClass('myClass') %}
{# do stuff #}
{% endif %}
Naming convention for components
.block {}
.block__element {}
.block--modifier {}
.block__element--modifier {}
links--node.html.twig (classy)
{% if links %}
{% include "links.html.twig" %}
{% endif %}
links.html.twig (classy)
{% if links -%}
{%- if heading -%}
{%- if heading.level -%}
<{{ heading.level }}{{ heading.attributes }}>{{ heading.text }}{{ heading.level }}>
{%- else -%}
{{ heading.text }}
{%- endif -%}
{%- endif -%}
{%- for item in links -%}
-
{%- if item.link -%}
{{ item.link }}
{%- elseif item.text_attributes -%}
{{ item.text }}
{%- else -%}
{{ item.text }}
{%- endif -%}
{%- endfor -%}
{%- endif %}
field.html.twig
Custom field.html.twig
field--field-hero-header.html.twig
Combines Include and Extends
{% embed "teasers_skeleton.twig" %}
{# These blocks are defined in "teasers_skeleton.twig" #}
{# and we override them right here: #}
{% block left_teaser %}
Some content for the left teaser box
{% endblock %}
{% block right_teaser %}
Some content for the right teaser box
{% endblock %}
{% endembed %}
Can now add libraries within twig templates
{{ attach_library('contextual/drupal.contextual-links') }}
Some markup {{ message }}
Careful - can impact aggregation / performance
https://www.drupal.org/project/styleguide
Many options
npm install kss --save-dev
npm install grunt-kss --save-dev
// Cards
//
// Multiple cards included in a grid
//
// Markup: cards.twig
//
// Style Guide: Patterns.Cards
.cards {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
grunt kss
or:
kss-node --source sass --destination styleguide --css ../css/style.css --builder=builder/twig
Behavior Driven Development Framework
@javascript
Scenario: Footer style matches style guide
Given I am an anonymous user
And I am on "assessments/practice-assessments"
When I am browsing using a "phone"
Then "body" should have a "background-color" css value of "rgb(112, 84, 125)"
And "#page" should have a "background-color" css value of "rgb(255, 255, 255)"
And "footer" should have a "padding-top" css value of "50px"
And "footer" should have a "padding-bottom" css value of "30px"
View Gist for detail of steps
Screenshot Comparison Tool
Selenium Bindings for NodeJS
Strengths: interactivity, easier to target components.
npm install webdriverio@3.4.0 webdrivercss@2.0.0beta-rc1 selenium-standalone --save-dev
./node-modules/.bin/selenium-standalone install
Also requires graphicsmagick
wdio-tests.js
var wdio = require("webdriverio");
var webdrivercss = require("webdrivercss");
var assert = require("assert");
var options = {
desiredCapabilities: {
browserName: "chrome"
}
}
var browser = wdio.remote(options);
webdrivercss.init(browser, {
screenshotRoot: "screenshots"
});
function assertShots (err, shots) {
assert.ifError(err);
Object.keys(shots).forEach(function(element) {
shots[element].forEach(function(shot) {
assert.ok(shot.isWithinMisMatchTolerance, shot.message);
})
});
};
browser
.init()
.url("http://testing-d8-theme.dd:8083/cards")
.webdrivercss("cards", [
{
name: "cards",
elem: ".cards"
}
], assertShots)
.end();
Some simple interactivity
browser
.init()
.url(config.url)
.click(".fa-bars")
.webdrivercss("navigation", [
{
name: "Off Canvas Menu",
elem: ".sidebar-offcanvas"
}
], assertShots)
.end();
* Requires Components Module *
card.twig
{{ header }}
{{ copy }}
node--article--card.twig
{% include "@components/card/card.twig"
with {
"img_src": file_url(node.field_image.entity.fileuri),
"img_alt": content.field_image.0['#item'].alt,
"header": label,
"copy": content.body
}
%}