<onWebFocus />

Knowledge is only real when shared.

Color and Project Configuration

February 2022

Using colors in web development and configuring projects.

Complementary Color

Primary

#00FF00

rgb(0, 255, 0)

Complementary

#FF00FF

rgb(255, 0, 255)

Colors are mostly a decorative element for websites with minimal guiding properties. To avoid using too many colors a design usually consists of two different colors used throughout the design. Often they are simply called primary and secondary (or accent) color. A more descriptive naming that is used in this post is highlight and interact. Here color is mainly used to highlight important parts or parts where the user can interact with something. Complementary colors often fit very well together and the above tool generates the complementary color for any color picked.

Different Formats

The most popular format for colors is the hex triplet. It consists of three bytes each describing the amount of either red #FF0000, green #00FF00 or blue #0000FF. The RGB format is pretty much the same but written with regular numbers or a percentage like rgb(255, 0, 0) or rgb(100%, 0%, 0%). While RGB is rarely used RGBA with an alpha channel indicating the opacity is very popular for web development. Opacity can be any value between 0 (transparent) and 1 (opaque). A semi-transparent red would look like rgba(255, 0, 0, 0.5). HSL uses a totally different way to describe colors better aligned with human vision but is rarely used in web development or design. Red in HSL can be written in two ways hsl(0, 100%, 50%) or hsl(360, 100%, 50%). The first value called hue goes full circle with a degree value between 0 and 360 covering the color spectrum of the rainbow. The second value called saturation describes the percentage to which color is used. Setting saturation to zero will turn an image into black and white. The last one lightness describes how much black or white should be added. At 50% it's the color defined with hue while other percentages make it either darker hsl(360, 100%, 25%) or lighter hsl(360, 100%, 75%).

Colorpicker Plugins

Colorpickers are usually based on the HSL format. Displaying the full hue spectrum as a slider while also allowing to adjust the dimensions of saturation and lightness. This type of colorpicker is also used by most design tools like figma. react-colorful seems to be the most popular picker of this sort. Depending on the context of the application it's sometimes better to offer another way to pick colors even sometimes by restricting the choice and displaying all available colors.

Inspired by the island of Burano near Venice and out of the need for a simple color picker in React I've set out to create burano. Burano exposes a Color component that will display a simple tool to let the user pick a color on a website. At the time I couldn't find react-colorful to which it's very similar and also allows to pick a transparency value. The most important thing to look for with color pickers is bundle size as plugins that support many different types are usually bloated while a typical application only requires one type.

import React, { useState } from 'react'
import { ColorPicker } from 'burano'

export const MyPicker = () => {
  const [color, setColor] = useState('#00FF00')

  return <ColorPicker color={color} onColor={setColor} />
}

Project Configuration

Configuration is a core part of Web Development. As soon you set up a new node project and install some dependencies with npm there will be a package.json file hosting arbitrary configuration. Over time more and more configuration will be added to the package.json and other configuration files like webpack.config.js or .babelrc.

There have been so many configuration files that it has become completely normal to place all these mere configuration files in the root folder. To make the actual source code files better browsable and easier to find we have put them all inside a src folder. While the source code is almost always the only thing subject to change during development it's no longer placed in the root where it can be found without an additional click. The root now mainly hosts the configuration files which have mostly been copied from a tutorial or are copied over from another project.

Since most of this configuration could be shared among projects several wrapper build tools like create-react-app have popped up and include a lot of configuration built-in so that in most cases one can get started immediately. While these tools somewhat eliminate many configuration files it's not a primary focus and the source code still lives in a separate folder.

To alleviate theses issues I've developed papua a build tool for websites leveraging webpack similar to create-react-app. Apart from the default package.json and a .gitignore file there are no additional configuration files. This means that all source code can be placed in the root and navigated more easily.

Many plugins that require configuration also allow a configuration file to be referenced from inside the package.json. papua is leveraging this an upon installation will add those references pointing to files inside the newly installed node_modules/papua/configuration.

{
  "name": "my-site",
  "scripts": {
    "build": "papua build",
    "start": "papua start",
    "test": "papua test"
  },
  "papua": {
    "entry": "common.ts",
    "tsconfig": {
      "compilerOptions": {
        "removeComments": true
      }
    }
  },
  "dependencies": {
    "papua": "^1.0.0"
  },
  "prettier": "papua/configuration/.prettierrc.json",
  "eslintConfig": {
    "extends": "./node_modules/papua/configuration/eslint.cjs",
    "rules": {
      "import/no-extraneous-dependencies": 0
    }
  },
  "stylelint": {
    "extends": "papua/configuration/stylelint.cjs"
  },
  "engines": {
    "node": ">= 14"
  }
}

Building, testing, linting all happen through scripts supplied through papua binaries. Custom configuration can be added through the "papua" property inside package.json and will be picked up during installation. Some configuration files like jsconfig.json / tsconfig.json cannot be referenced from package.json and is generated during install but also added to gitignore so that it's easy to ignore and never gets committed to the repository.

Using this innovative approach the source code can finally be placed in the root again. To develop npm plugins a plugin called padua using the same approach was created. This allows for the quick creation of minimal plugins using all the convenient tools that would otherwise require tons of configuration files. To create servers squak uses the same approach.

Since one is no longer reliant on copy and pasting configurations between projects updates to configurations can be rolled out to all projects without the need to touch anything.