Developing
Wave has everything you need to get started building web interfaces at Volue. Develop a consistent and accessible user interfaces much faster using a range of pre-built components.
Developing
#
Authenticating to package registrySince @volue
is a private NPM scope, your project (both locally and in CI pipeline) needs to be authenticated with NPM registry to fetch packages.
Wave packages are published to both official npmjs.com registry and our organization's Github Package Registry.
The best way to authenticate with npmjs.com registry is using an access token. You can find pre-generated authentication token with read-only permissions required to download Wave packages in the wiki page on GitHub.
# 1. Do this on your local machine and commit the `.npmrc` to gitcd path/to/your/appecho '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> .npmrc# 2. Add this environment variable both locally and on your CI/CD# Substitute `READ_ONLY_NPM_TOKEN` with a real token:# https://github.com/Volue/wave/wiki/NPM-authentication-tokenexport NPM_TOKEN=READ_ONLY_NPM_TOKEN
If, for some reason, you're not able to access the NPM authentication token page, please contact the Design System team.
#
InstallationInside your project directory, install Wave by running either of the following:
npm install @volue/wave @volue/wave-react --save
yarn add @volue/wave @volue/wave-react
Bleeding edge pre-release version with the most recent features, can be installed by appending @next
tag to the package names:
yarn add @volue/wave@next @volue/wave-react@next
#
Include Wave core assetsFor Wave to work correctly, you need to include its core assets, such as stylesheets, icons and web fonts.
To copy core assets from node_modules/@volue/wave
to a location where you store your other bundled and minified assets for production, you may use copy-wave-assets
command:
npx copy-wave-assets ./dist# oryarn copy-wave-assets ./dist
copy-wave-assets
will create a directory named wave
in the location you’ve specified (./dist
in the example above). See copy-wave-assets -h
for more information.
It is recommended to add a script to your package.json
that runs copy-wave-assets
and call it whenever the build is executed to make sure you’ve always got the latest assets copied over:
"scripts": {"sync-wave-assets": "npx copy-wave-assets ./public","build": "npm run sync-wave-assets && react-scripts build","start": "npm run sync-wave-assets && react-scripts start"}}
Alternatively, you could use tools such as CopyWebpackPlugin to move core Wave resources to your assets directory as part of your build process.
#
Include assets in your HTML templateOnce you have a copy task in place and and the assets are copied over, you can serve them using <link>
tags in your root HTML template.
-
Add links to favicons
-
Add inline style with @font-face rules in the
<head>
to load initial, highly optimized versions of our web fonts.Remember to preload the initial web fonts using
<link rel=”preload”>
. -
Inline
wave-head.min.js
in the<head>
of your HTML template. This is a small chunk of logic that will asynchronously load full versions of our web fonts to enable more stylistic variants and features.wave-head.min.js
could be specified as<script src="wave/wave-head.min.js">
, however it's best to save additional network request for a render-blocking resource.You can achieve the inlining by using interpolation syntax of html-webpack-plugin (see example code below).
You can customize the path to the web fonts directory by adding
<meta name="fontsDir" content="/path/to/fonts">
in the<head>
. By default fonts will be looked up in/fonts
directory. -
Add link to the CSS bundle to include the core Wave styles.
-
Your index.html
should resemble:
<!doctype html><html><head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width,initial-scale=1" /><meta name="theme-color" content="#00829b" /><title>...</title><!-- Favicons --><!-- make sure to place `favicon.ico` in the root of your web app (required for legacy browsers) --><link rel="icon" href="/favicon.ico" sizes="any" /><link rel="icon" type="image/svg+xml" href="/wave/images/favicon.svg" /><linkrel="icon"type="image/png"sizes="192x192"href="/wave/images/favicon-192.png"/><link rel="apple-touch-icon" href="/wave/images/favicon-180.png" /><!-- Wave webfonts --><linkrel="preload"href="/wave/fonts/SourceSansPro-Regular-initial.woff2"as="font"type="font/woff2"crossorigin/><linkrel="preload"href="/wave/fonts/FKDisplay-Regular-initial.woff2"as="font"type="font/woff2"crossorigin/><style>@font-face {font-family: 'Source Sans Pro';src:url(/wave/fonts/SourceSansPro-Regular-initial.woff2) format('woff2'),url(/wave/fonts/SourceSansPro-Regular-initial.woff) format('woff');font-display: swap;}@font-face {font-family: 'FK Display';src:url(/wave/fonts/FKDisplay-Regular-initial.woff2) format('woff2'),url(/wave/fonts/FKDisplay-Regular-initial.woff) format('woff');font-display: swap;}</style><!-- wave-head.min.js inlined --><script><%= require('!!raw-loader!@volue/wave/dist/core/wave-head.min').default %></script><!-- Wave core styles --><link rel="stylesheet" href="wave/wave.min.css" /></head><body><!-- Embedded Wave icons sprite --><div id="svgSpritePlaceholder" class="is-hidden" aria-hidden="true"><%= require('!!raw-loader!@volue/wave/dist/core/sprite.svg').default %></div><div id="appRoot"></div></body></html>
#
Use the componentsAll components are available as named exports from @volue/wave-react
.
Import any of the components in your React project and use them in your interface:
import { Collapsible, Button, SvgIcon } from '@volue/wave-react';const Component = () => {return (<Collapsible><Collapsible.Trigger as={Button} variant="outline"><SvgIcon iconName="chevronDown" /> {'Toggle panel'}</Collapsible.Trigger><Collapsible.Panel>{'Panel content'}</Collapsible.Panel></Collapsible>);};
Refer to the individual component documentation for recommended usage and API references for each component.
#
Styling APIs#
cssThe css
property is available on all of our components to allow you to contextually style them when necessary.
It provides a superset of CSS (i.e. it contains all CSS properties and selectors in addition to custom ones) so it's intuitive to pick up and start working with right away if you're comfortable with CSS.
You can pass in an object of CSS key-value pairs and the component will apply those styles as a class on the rendered component.
The benefit of using the css
prop as opposed to writing inline styles is that we can directly access values from our design tokens to ensure consistency, write responsive styles by referring to the breakpoints defined in the theme etc:
import { Box } from '@volue/wave-react';<Boxcss={{// we can write standard CSS herecolor: 'red',// we can also access design tokensbackgroundColor: '$backgroundNeutralSubtle',padding: '$spacingM',// write inline responsive styles'@mqLargeAndUp': {color: '$foregroundAccentModerate'},// and utilise shorthand utilitiesmb: '$spacingXl'}}/>;
Box component is a low-level primitive that lets you work with the css
prop.
When working in a TypeScript codebase our design token options will show up with autocompletion depending on the CSS property used.
The css
prop is great for customizing only a specific instance of a given component, by defining one-off styles.
#
styled@volue/wave-react
also exports the underlying styled()
function that is used to create styled components with access to the css
prop.
import { styled } from '@volue/wave-react';const MyStyledComponent = styled('div', {color: '$foregroundAccent',size: {small: {padding: '$spacingS'},large: {padding: '$spacingL'}}});() => <MyStyledComponent size="large" />;
Box component is just a styled
div element.
In contrast to the css
prop, styled()
function is ideal for building components that need to support a wide variety of contexts.
It allows you to create custom components, with similar capabilities as Wave's standard components.
In addition to the base component styles, styled()
lets you define a single variant, multiple variants, and even compound variants which allow you to define styles based on a combination of variants.
Those variants can be applied conditionally or responsively.
Refer to the Stitches docs to read more about the difference between css
and styled()
.
#
Example React projectsBelow you will find various project templates on GitHub, demonstrating the integration with Wave and very basic components usage.
You might also take a look at our internal boilerplate for developing React apps, which comes integrated with Wave.