The page navigation is complete. You may now navigate the page content as you wish.
Skip to main content

Icon usage


There are four types of icons: Outlined, Filled, Off, and Contained.


Outlined icons are icons with a standard outline.

Use Outlined icons by default.

Example of outlined icons


Filled icons are icons with a solid fill and are indicated by -fill in the icon name.

Use Filled icons to show a toggled state or for contrast with Outlined icons.

Example of filled icons

Indicating a toggled state

For objects that can be toggled on/off, show the Outlined icon for off and the Filled icon for on.

Example of toggled state icons

Using for contrast

If contrast against other icons is important, use Filled for the more important icon(s).

For example, when showing one failure in a list of 20 otherwise successful builds, use x-square-fill while keeping the remaining icons in the Outlined style so the failure is more prominent.

Example of contrasting icons


Off icons are icons including a strike-through and are indicated by -off in the icon name.

Use Off icons to indicate something is disabled, unavailable, or will return a toggled icon off.

Example of off icons

Indicating a disabled or unavailable icon

When needing to indicate an action is disabled or unavailable, consider pairing an Off icon with the color style Foreground/Disabled and cursor property value not-allowed.

Return toggled state back off

If an object is toggled on and it can be toggled off, consider showing the Off icon on hover to indicate that clicking the icon again will toggle the object back off.

Example of toggling icons off


Contained icons are icons with a containing shape and are indicated by their shape type in the icon name, e.g., -circle, -square, etc.

Use contained icons for emphasis in the hierarchy.

Examples of contained icons

If an object can have multiple states, use a Contained icon for the overall parent state and the Outlined icon(s) for the children’s state(s).

Example of contained icons in context


Icons are optimized for two icon sizes: 16px and 24px.

Use 16px icons by default in product interfaces and 24px icons for empty states.

Resizing icons

There may be cases where 16px and 24px sizes don’t fit a design. Icons can be resized but be aware that the design is not optimized for resizing. Therefore, only resize icons as necessary and sparingly.

Example of available icon sizes


Icons frequently represent different states within product interfaces, most commonly as states of an object or states of feedback.

States of an object

Some objects can return a state, e.g., a Build, Run, Cluster, etc. Objects are typically displayed in lists or as cards and include their state when presented to the user.

Examples of object states

States of feedback

Feedback is presented in response to user interaction, such as a displaying a success message after submitting a form or a warning when a user nears their usage limit.

Examples of feedback states

Common icons

Some icons represent common actions within our products.

Editing actions

Examples of common edit icons

Examples of common navigation icons

Help actions

Examples of common help icons

Migrating from Structure

Choosing the correct icon

When migrating icons from Structure, reference our mapping of icon names between Structure and Helios.

Choosing the correct size

Structure icon size Helios icon size
<= 20px 16px
>= 21px 24px*

*If 24px seems too large, consider using the 16px icon and reworking the interface for a better fit.


How to use icons

Icons can be used in many ways. The package can be installed as an Ember addon for the convenience of using a component with strong defaults. It can also be consumed in React applications via direct import of the SVG file or as a standalone React/SVG icon component.

Using icons in Ember apps

Installing the ember-flight-icons addon

yarn add @hashicorp/ember-flight-icons

Because this addon exposes a data-test-icon helper, we recommend installing ember-test-selectors which strips out all data-test-* attributes for production builds.

Understanding the component

The component comes with the following defaults:

  1. fill attribute: set to currentColor.
  2. id attribute: a unique, automatically generated id.
  3. aria-hidden attribute: set to true.
  4. height and width: default size of 16x16 (px).
  5. stretched: if the SVG should have 100% width/height (stretch to fill the parent)—defaults to "false".
  6. (CSS) class: flight-icon, flight-icon-{name}, flight-icon-display-inline.
  7. CSS display: set to display:inline-block.
  8. data-test-icon attribute: for the author’s testing convenience; set to the value of the @name property.

This makes the base, required invocation quite terse—@name is the only property that requires specification. So this invocation:

<FlightIcon @name="alert-circle" />

Renders to this (where the ID will be unique each time):

    class="flight-icon icon-alert-circle display-inline"
    viewBox="0 0 16 16"
    <use href="/@hashicorp/ember-flight-icons/icons/sprite.svg#alert-circle-16"></use>

The <use> element will then render the correct SVG to the shadow DOM.

Customizable properties

The following properties are customizable:

  1. fill
  2. size
  3. stretched
  4. additional CSS classes
  5. display

To customize the fill attribute, set the @color value. To ensure consistency with our design language, we recommend using one of the pre-defined variables:

<FlightIcon @name="zap" @color="var(--brand)" />

Other accepted values include named colors and color values themselves (e.g., hex, rgb, etc).

<FlightIcon @name="zap" @color="rebeccapurple" />
<FlightIcon @name="zap" @color="rgb(46, 113, 229)" />

To use the 24px icon size, set the @size value:

<FlightIcon @name="zap" @size="24" />

To have the icon fill the parent container (width: 100%, height: 100%, display: block), set the @stretched attribute:

<FlightIcon @name="zap" @size="24" @stretched={{true}} />
CSS classes

To append additional classes to the component, add class with value(s):

<FlightIcon @name="triangle-fill" class="ds-rotate-90" />
CSS display

To change the default display from inline-block to block, set @isInlineBlock to false:

<FlightIcon @name="triangle" @isInlineBlock={{false}} />
<FlightIcon @name="triangle-fill" @isInlineBlock={{false}} />
Animated icons

Animated icons (e.g., "loading" and "running") are animated by default, meaning no additional properties are needed.

Note on accessibility

A prefers-reduced-motion media query will automatically disable the animation if users set this preference in their environment.

<FlightIcon @name="loading" @size="24" />

Using icons in React apps

To use icons in a React application, install the @hashicorp/flight-icons package and import the icons as either inline SVGs or as a standalone React/SVG component.

For more details about the decision to add this functionality, visit this pull-request.

Installing the flight-icons package

To install, run:

yarn install @hashicorp/flight-icons

Importing icons as inline SVGs

Single icons can be imported and used directly as SVG files using <InlineSvg> provided by @hashicorp/react-components.

Since this is just an SVG asset, no props can be passed. You should refer to the <InlineSvg> documentation to know how to apply color and size to the SVG icon.

// import the SVG file (using 'require')
const iconArrowRight = require('@hashicorp/flight-icons/svg/arrow-right-24.svg?include');
// or import the SVG file (using 'import')
import iconArrowRight from '@hashicorp/flight-icons/svg/arrow-right-24.svg?include';

// elsewhere in the file
<InlineSvg src={iconArrowRight} />

// alternatively you can also use a similar approach
<InlineSvg src={require('@hashicorp/flight-icons/svg/arrow-right-24.svg?include')} />

Importing icons as React/SVG components

Single icons can be imported and used directly as standalone React/SVG components:

// import the React/TypeScript file (using 'require')
const { IconArrowRight24 } = require('@hashicorp/flight-icons/svg-react/arrow-right-24');
// or import the React/TypeScript file (using 'import')
import { IconArrowRight24 } from '@hashicorp/flight-icons/svg-react/arrow-right-24';

// elsewhere in the file
<IconArrowRight24 />

Customizable properties

The component exposes the following props:

  1. color—the color (applied as fill) to the SVG—by default is currentColor but any valid HTML/CSS color is accepted.
  2. title—the title of the SVG—by default, the icon has an aria-hidden attribute applied to it because it is expected to be used in context (check out § Accessibility); if instead you need to use it without text associated to it, you have to pass a title attribute to make it accessible.
  3. ...props - any other prop passed to the component will be applied via spread.

The size of the icon is determined by the size of the asset imported (each icon is exported in two sizes, 16 and 24). If you need a different size, use CSS to override its intrinsic size.

Aligning icons

By default, the FlightIcon component has an inline-block display value (this can be changed using the @isInlineBlock argument). This means that the icon behaves like an inline element, and that if you want to vertically align it in relation to other sibling elements, you have to use CSS to achieve the expected result.

For example, to visually center an icon with a generic text node, you will need to use a parent flex container with align-items: center.

Avoid using vertical-align: middle

Just setting vertical-align: middle in the parent container doesn’t necessarily achieve a vertical alignment.

This is because the middle alignment is not calculated in relation to the whole text “block” but to its “x-height”. To learn more, read about how vertical-align works in CSS.

Animated icons

Some of the icons are meant to be animated (e.g., “loading” and “running”). To use them, import the CSS that controls the icons’ animation:

// the path here depends if you’re using 'svg-react' or 'svg' icons 
@import ~@hashicorp/flight-icons/svg-react/animation.css';

Then declare them the same way you would with any other icon.

// if you’re using the 'svg-react' icons
import { IconLoading16 } from '@hashicorp/flight-icons/svg-react/loading-16'
<IconLoading16 />

// if you’re using the 'svg' icons
import svgLoading16 from '@hashicorp/flight-icons/svg/loading-16.svg?include'
<InlineSvg src={svgLoading16} />

Note on accessibility

A prefers-reduced-motion media query will automatically disable the animation if users set this preference in their environment.


Accessibility support for SVGs is inconsistent across browsers and assistive technology. Currently, the best practice is to set the aria-hidden attribute to true on the SVG itself. This means that the icon (both the singular icon and the icon component) will need to be used in context. The icons themselves are for presentation purposes only and should never be used on their own.

However, as a temporary bridge, while we work to provide the accessible components in the design system, we have provided the ability to add a title element to the Ember component by defining a value for the @title property. This is a temporary measure, and we strongly encourage UI engineering teams to work with their designers and plan to convert any standalone icon use.

Examples of correct use

<button aria-label="Check activity">
    <FlightIcon @name="activity" />
    Activity report <FlightIcon @name="activity" />

Some additional best practices include:

Migrating from Structure

Choosing the correct icon

When migrating icons from Structure, reference our mapping of icon names between Structure and Helios.

It’s possible to write codemods to automate this migration. If you’re interested in learning more, contact #team-design-systems (Internal only).