Git Product home page Git Product logo

common_design's Introduction

OCHA Common Design System

  • Full-width header and footer
  • Full-width components

Common Design base theme for Drupal 8/9

There is a sub theme included in this repo.

  • This can be used as a starting point for implementations. Add components, override and extend the base theme as needed. Copy the common_design_subtheme directory to /themes/custom/ and refer to its README. All the implementation-specific work should happen in the sub theme.

Drupal components:

Additional components:

  • Typography
  • Component library
  • Favicons and OCHA branded assets based on https://brand.unocha.org
  • Node workflow for frontend development
    • SASS
    • Sourcemaps (to show which specific Sass file contains styles during local development)
    • Autoprefixer
    • Sass and JS linting
    • SVG sprite
    • E2E tests

Getting started

  1. Clone this repo to /themes/contrib/ or install using composer require unocha/common_design.
  2. Copy the common_design_subtheme directory to /themes/custom/.
  3. In the Drupal Admin, go to Appearance, find 'OCHA Common Design sub theme' and select Enable and set default.

To contribute to common_design base theme or sub theme development and/or to customise the sub theme

  1. Run nvm use in theme folder to ensure the correct node version.
  2. Install the dependencies: npm install
  3. For development, run npm run sass:watch (this includes an initial linting and sourcemaps) or run npm run sass:compile-dev to compile.
  4. Run npm run sass:build for final CSS generation.
  5. For twig debug and local development see Disable Drupal 8/9 caching during development.

Drupal 8/9 core have helper classes for accessibility. Hide content properly using official drupal.org docs.

CSS

This project uses Sass. To make changes edit the .scss files in the sass/ folder, do NOT edit the files in css/ directly.

  • npm run sass:build — compile production-ready CSS.
  • npm run sass:watch — watch for changes and automatically rebuild the CSS during local development.
  • npm run sass:lint — linting report only.
  • npm run sass:lint-fix — linting report, plus automatically fix any errors that the tool can safely handle.

The stylelintrc.json config file extends Drupal core stylelint config. Run npm install in your site's html/core directory to install the stylelint plugins if there are errors indicating missing packages.

When possible, use Jenkins to run the sass:build task on build to generate the CSS within your website's deploy job.

Follow Drupal CSS coding standards and best practices

JS

Javascript files should be added to js/ and defined as a library in common_design.ibraries.yml

Instead of grouping all JS in one file, each component has its own JS file associated with it. They have been built to be reused, allowing you to mix and match any combination of JS files and use each as a dependency without altering the original file. The general pattern to reference the method of a behavior is:

// Use a method called "methodName" inside the same Behavior file
this.methodName();

// Use a method called "methodName" defined in cd-dropdown.js
Drupal.behaviors.cdDropdown.methodName();

Using this works for most functions except ones which are assigned to event listeners. For those, we have prefixed all of them with the word handle — and despite being contained within the same Behavior, you'll need to reference internal functions using the full Behavior name (see second example above, as if it were outside your Behavior).

(function (Drupal) {
  'use strict';

  Drupal.behaviors.exampleBehavior = {
    attach: function (context, settings) {
      // Assign handleClick as an event listener. When assigning the handler
      // it is correct to prefix the method name with `this`
      document.addEventListener('click', this.handleClick);
    },

    sendAlert: function (message) {
      window.alert(message);
    },

    handleClick: function (ev) {
      // ❌ WRONG:
      //
      // Inside this event listener handler, we do not have access to the
      // Behavior object as `this` so this.sendAlert() will not be defined
      // and the following error will occur:
      //
      // Uncaught TypeError: this.sendAlert is not a function
      this.sendAlert(ev.target);

      // ✅ CORRECT:
      //
      // Referencing the Behavior as defined in Drupal object will work.
      Drupal.behaviors.exampleBehavior.sendAlert(ev.target);
    }
  };
})(Drupal);

Follow Drupal JS coding standards and best practices

Fonts

This projects defines a few CSS Vars for font-families that use Google Fonts. The actual fonts must be loaded by enabling them individually (see below). You can read official guidance on OCHA's visual identity website.

Here are the technical details relating to the theme itself:

  • Roboto is included by default as a sass partial in sass/base/_fonts.scss and imported in styles.scss. This means Roboto font is compiled as part of styles.css
  • Additional fonts for advanced typography and other languages which don't use Latin character sets are available as Drupal Libraries. The list is defined in common_design.libraries.yml. For performance reasons, we do not include these by default. If your website must support character sets that are not included in the base-theme, refer to the sub-theme's Libraries file common_design_subtheme.libraries.yml to see a commented-out example helping you create your own Drupal Library.

Enabling individual fonts

The fonts can be enabled one of two ways.

First, in the common_design_subtheme by adding the relevant base-theme libraries as a dependency to the global styles in the common_design_subtheme.libraries.yml:

global-styling:
  css:
    theme:
      css/styles.css: {}
  dependencies:
    - common_design/fonts-advanced
    - common_design/fonts-arabic
    - common_design/fonts-chinese
    - common_design/fonts-russian

Second, you can also enable them in the Drupal Admin UI under the sub-theme theme settings at /admin/appearance/settings/common_design_subtheme.

Task management

This project uses some Node packages for Sass compilation, watching and linting, JS linting and SVG icon sprite generation. See scripts in package.json.

To get a list of commands, do npm run and it will output all possible options.

Icons

The available icons can be found in img/icons

There are two techniques used, SVG symbol sprite with the <use> element, and SVG as a background-image, depending on context. The sprite technique is preferred. We only use svg as a background image when using the sprite isn't possible.

1. SVG sprite

SVG symbol sprite with the <use> element. The SVG sprite is loaded as a single asset in the html.html.twig before the closing body tag. Each icon within the sprite can be referenced by its ID eg.

<svg class="cd-icon cd-icon--arrow-down" width="16" height="16" aria-hidden="true" focusable="false">
  <use xlink:href="#cd-icon--arrow-down"></use>
</svg>

Each icon should have the class cd-icon and a BEM selector if needed e.g. cd-icon--arrow-down. We can create associated CSS rules to control dimension and fill.

Each icon should have reasonable width and height attribute values. These control the SVG display when the CSS is slow or does not load. If the icon is decorative, add aria-hidden="true" focusable="false" to remove the element from the accessibility tree.

We're using https://github.com/jkphl/svg-sprite node package. See https://una.im/svg-icons for more details.

2. SVG background-image

SVG as a background-image value, usually on a pseudo element. The SVG fill colour is added as an attribute in the SVG file. The icons are black by default. If you need another color, it's best to copy the icon and manually adjust the fill/stroke to suit your needs. Rename the copy to include the color in the filename eg. arrow-down--white.svg.

Generating the icons sprite

As defined in the node scripts, all new icons should be placed in the img/icons directory. Run npm run svg:sprite to generate a new sprite. This generates the sprite SVG img/icons/cd-icons-sprite.svg and it creates an html page with all SVGs for reference img/icons/sprite.symbol.html.

Browser support

Progressive enhancement approach to layout, using Feature Queries to detect support for flexbox and grid.

Favicons

OCHA default favicons are provided. Update these with your logo.

http://realfavicongenerator.net/ is a good tool for generating favicons.

Testing

What we test

See Browsers to test and Draft - Supporting a global audience.

We use browserstack for browser and device testing. We can test using our local development environments, select specific browsers for manual testing, and generate screenshots of many browsers at once. Join the Flowdock Developers channel for access.

How we test

There are e2e test using Jest and Puppeteer in the base and sub theme. There is a repo for Visual Regression testing using backstopjs and a Jenkins Job to run VRT on the server. Depending on the json configuration files, we can generate screenshots from lists of URLs (including authenticated user pages), of multiple viewport dimensions, and capture keypress, hover and click actions.

Depending on the project, we run tests via Travis CI. For the common-design-site repo we run PHP lint and Drupal coding standards checks, and compile the theme's sass files. These are common among most projects. Additionally, we install Drupal, import the config, import a database of sample data and run a web server so we can then run the e2e tests.

There is an open issue to integrate Lighthouse performance and accessibility testing OPS-7526

E2E testing

# Install dependencies for your host machine.
npm i

# Run all E2E tests in headless mode. The console will output the results.
npm run e2e

# See the tests run in a visible browser window with --debug
npm run e2e -- --debug

# If you want to run a limited number of tests, specify a string with the -t
# argument. It will parse all of the describe() blocks and only run tests when
# it matches the string you supply.

# All tests that include 'OCHAServicesDropdown'.
npm run e2e -- -t 'OCHAServicesDropdown'

# Only tests in 'Subtheme: OCHAServicesDropdown' block.
npm run e2e -- -t 'Subtheme: OCHAServicesDropdown'

# All 'OCHAServicesDropdown' test except blocks including 'Subtheme'.
npm run e2e -- -t '^(?!.*Subtheme).*$OCHAServicesDropdown'

# All tests except blocks including 'Subtheme'.
npm run e2e -- -t '^(?!.*Subtheme).*$'

Progressive Web App

web.brand.unocha.org website uses the Drupal PWA module

There is a site.webmanifest file available in the sub theme as an alternative to the module, if all you want is the Web Manifest, and you don't want offline capability. The manifest file should be adjusted per implementation, and added using a <link> element in the <head>, with additional configuration needed. See the Manifest documentation for implementation details.

Translations

Arabic, French and Spanish string translation files are available for the Common Design Header and Footer user interface, for example the OCHA Services in the header and the OCHA mandate in the footer. Refer to the .po files in the translations directory and the README.

common_design's People

Contributors

left23 avatar rupl avatar orakili avatar lazysoundsystem avatar cafuego avatar dependabot[bot] avatar attiks avatar berliner avatar

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.