Installing Origami components with a package manager (manual build) gives you more granular control over their styling and their behaviour within your project. It requires more set up though, compared to using the Origami Build Service, so we’re providing an in-depth walkthrough for building a page for an article about fruit.
This tutorial assumes that:
We will need a folder structure for our page. So let’s begin by creating a new directory to work in.
mkdir o-fruit-demo && cd o-fruit-demo
Eventually, we’ll have a folder structure that separates our HTML, CSS, JavaScript, dependencies and assets. Let’s start by adding an index.html
to the root of our new project with some boilerplate HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Origami Project</title>
<link rel="stylesheet" href="/main.css">
<script async src="/main.js"></script>
</head>
<body>
</body>
</html>
The link
and the script
tags are pointing at our public assets, which will be available once we have performed a build step and compiled our source code. That source code will be written in plain Javascript and in SCSS, and each of those will be in their individual folders in our project:
mkdir src && touch src/main.js src/main.scss
Now we’re ready to start adding components to our page.
With the exception of JavaScript-only components, all of Origami’s components rely on markup. This markup, combined with the styling and the functionality, is what determines how a component will look and behave on a page. So before we can style anything, we’ll need to add some component markup to our page.
o-grid will determine how our content sits on our page. To begin, let’s add the following to the <body>
in our index.html
:
<div class="o-grid-container">
<div class="o-grid-row o-typography-wrapper" data-o-grid-colspan="center 8">
</div>
</div>
We want to share some fruit facts, so let’s add some content to that inner div
:
<h1>Funky Fruit Facts</h1>
<h2>Durian</h2>
<p>Due to its overpowering smell, durian has been banned on many types of public transport across Thailand, Japan and Hong Kong. In Singapore, the fruit is banned across all types of public transportation and even taxis have signs to let you know they refuse to carry passengers transporting the smelly fruit.</p>
<h2>Dragonfruit</h2>
<p>The cactus flower that produces dragon fruit survives only a single night. It blooms in the evening, ready for pollination by bats and moths, and wilts the very next day. The very brief pollination period, however, is sufficient for the plant to bear fruits.</p>
<h2>Naseberry, aka Sapodilla</h2>
<p>The sapodilla tree supplies the building blocks for a number of products utilized by humans. Long ago, the Mayas and Aztecs would boil its ‘chicle’ sap, mold it into thick blocks and cut them into small pieces to chew. They were making the first chewing gum!</p>
Finally, we want to showcase the popularity of each fruit in a sortable table. To do that, we’re going to use the o-table
component.
This is a good time to highlight how the manual build process provides more flexibility, because we don’t need to include all the table variations provided by Origami - we can include the minimum features we need.
Let’s head over to the striped variation of o-table in the registry, and copy that HTML in under our content.
Now that we have set up the scaffolding for our page, we need to install those components so we can access their respective styles and functionalities.
All Origami components are available for installation via npm. They live in the Origami Registry, and are published to the public npm registry.
Next, we need to install our components as peer dependencies. We will opt to install them through the command line, and save them to a package.json
file. For the scope of this tutorial, all that needs to be in that file right now is:
{
"name": "o-fruit-demo"
}
Now we need to install our components, and we can save them all to our file by running:
npm install --save-peer @financial-times/o-grid @financial-times/o-typography @financial-times/o-colors @financial-times/o-table
And your package.json
should now look something like this:
{
"name": "o-fruit-demo",
"peerDependencies": {
"@financial-times/o-grid": "^6.0.0",
"@financial-times/o-typography": "^7.0.2",
"@financial-times/o-colors": "^6.0.8",
"@financial-times/o-table": "^9.0.2"
}
}
So that we can see our progress as we build the page, now is the time to implement our build step. What we need is something to bundle the JavaScript we write, and compile Sass to CSS for the browser. But build steps may vary per application or team, so setting up build tools is out of scope for this tutorial. So we can focus on how to use Origami components we are going to use the Origami Workshop tool.
As long as you have Node.js installed, you can run:
npx @financial-times/origami-workshop
This command will compile your code to a public
directory every time you make a change, and serve it locally for you to preview in a browser e.g. at htpp://localhost:3000
. You can leave that running in the background, and refresh your browser to see the styling changes we’ll be making in the next step.
Now we can begin styling our components. For this, all of our work is going to happen in our src/main.scss
file.
So we can monitor what projects component assets are being used, some components require a global Sass $system-code
variable is set. This should be the project’s biz-ops system code, but we can set it to test
for now in src/main.scss
:
$system-code: 'test';
To include the components Sass use @import
. For example this makes all o-grid
Sass mixins, functions, and variables available:
$system-code: 'test';
@import '@financial-times/o-grid/main';
By default Origami components do not output any CSS when you import them. This is so your project can granularly include only the CSS it needs from each component. To output a components CSS use its mixins, which are documented in the component README and Sassdoc. Most components include a primary mixin which matches the component name. These include all CSS by default and accept a map of options to include CSS for specific features. For the o-grid
component this is a mixin named oGrid
:
@import '@financial-times/o-grid/main';
// output all o-grid css
@include oGrid();
If we open our page in a browser window (visit http://localhost:3000
after running the origami-workshop command discussed above), we’ll see that our content is now centred on the page. This is because of the classes that we added to our outside div
at the very beginning.
We added an o-typography class to our inner div at the beginning of the tutorial, as well. It will apply styling just as the grid did, so the next—unguided—step, is for you to implement o-typography
in the same way we implemented o-grid
above.
Look at your page in the browser when you’re done - your headings and paragraphs should have received font families and styling of their own.
We’re going to get a little more specific with o-table since we’re after a particular variation.
We only want the base styling of a table, and some stripes to tell each row apart, so pass an options map to the oTable
mixin:
@import '@financial-times/o-table/main';
@include oTable($opts: ('stripes'));
Other options are documented in the README.
We’ll be using o-colors, which has a wide variety of colours in its palette. Since we don’t need all of the colours in the palette for this page, we will not include the primary mixin oColors
. Instead we will use some Sass functions o-colors
provides.
o-colors defines colours by name, e.g. “crimson”, and colours by usecase e.g. “page background”. We can use the Sass functions oColorsByName
and oColorsByUsecase
to get a colours hex value from our palette.
@import '@financial-times/o-colors/main';
body {
background-color: oColorsByUsecase('page', 'background');
}
As soon as your build has completed, visit your page again in the browser. You should have the pink that is characteristic of the FT as a background colour.
By default Origami components are tailored for public facing, ft.com products — these are known as “core brand” products. But Origami components offer tailored support for other contexts with component branding.
To choose a brand other than the default “core” brand, set the $o-brand
SCSS variable at the start of your root SCSS file, before importing any components.
To see this in action we can set our brand to “internal”:
$o-brand: "internal"; // Set brand before anything else.
@import '@financial-times/o-colors/main';
//...
As the colour palette for the “internal” brand does not include “paper” (FT pink), the background we set with o-colors
and the stripes of o-table
have changed. The typography of our project has also changed.
Now we will undo that by deleting $o-brand: "internal";
, making our project default to the “core” brand again.
For a list of supported brands and their purpose see component brands.
The final step in our tutorial involves adding JavaScript to our components. Not that all Origami components use JavaScript but of the components we have installed today o-table
does. We’ll be doing all of that work in src/main.js
.
There are multiple ways to initialise component JavaScript.
o.DOMContentLoaded
event.init
method.For this tutorial we will follow approach (1), however the other approaches are outlined below for reference.
Origami components listen for a custom event named o.DOMContentLoaded
in order to initialise. We’ll need to add that to our project so that the o-table
JavaScript can kick in.
For the purposes of this tutorial let’s follow this method and add the following to our JavaScript file:
import '@financial-times/o-table';
// Wait until the page has loaded
if (document.readyState === 'interactive' || document.readyState === 'complete') {
document.dispatchEvent(new CustomEvent('o.DOMContentLoaded'));
}
document.addEventListener('DOMContentLoaded', function() {
// Dispatch a custom event that will tell all required modules to initialise
document.dispatchEvent(new CustomEvent('o.DOMContentLoaded'));
});
Now you can sort fruit alphabetically by name or characteristic, or numerically by popularity.
For reference, we could instead have initialised all instances of the o-table using its init()
method.
The init()
method accepts two optional arguments, an HTMLElement
and an options object. What constitutes as ‘options’ is detailed in each components’ README.
import oTable from '@financial-times/o-table';
// Initialise all o-table instances on the page
oTable.init();
// == or ==
// Initialise all o-table instances
// found within a given DOM element
oTable.init(HTMLElement);
Another approach we could have taken is to initialise our single o-table
element specifically.
import oTable from '@financial-times/o-table';
// Initialise an o-table instance for the passed in DOM element
const myTableElement = document.querySelector('table');
new oTable(myTableElement);
We’ve given you an overview of how to build components manually. There is more information about each component, its variations, its individual behaviour and configuration in the Origami Registry. Here we’ve covered the fundamentals, but there are a few more aspects to the development of a product with Origami components that are important for compatibility and consistency, and we encourage you to read more about them: