Skip to main content

Icons

The kit has a small, fixed set of icons, shown with the Icon component. The components use them for Metrics, places and states. You can use them in your own screens too, so your icons match the kit's.

Loading…
Live editor
<Icon name="thermostat" />

Import​

import { Icon } from "@detriz-sh-kit/ui";

The component needs the kit's styles. See Design tokens.

Basic usage​

Pass the icon's name:

import { Icon } from "@detriz-sh-kit/ui";

<Icon name="home" />;

The icon set​

The icons are Material Symbols, in the Rounded style at weight 400. Only the icons below exist in the kit: name accepts these names only, and TypeScript tells you if you pass anything else.

Loading…
Live editor
function IconSet() {
  const names = [
    "airwave",
    "battery_full",
    "bolt",
    "co2",
    "door_front",
    "error",
    "grain",
    "home",
    "humidity_percentage",
    "humidity_mid",
    "light_mode",
    "lightbulb",
    "lightbulb-fill",
    "link_off",
    "refresh",
    "sensors",
    "stairs_2",
    "thermometer",
    "thermostat",
    "tv_gen",
    "wifi",
    "wifi_off",
  ];
  return (
    <div
      style={{
        display: "grid",
        gridTemplateColumns: "repeat(auto-fill, minmax(13rem, 1fr))",
        gap: "var(--shk-space-3)",
      }}
    >
      {names.map((name) => (
        <span
          key={name}
          style={{
            display: "flex",
            alignItems: "center",
            gap: "var(--shk-space-2)",
          }}
        >
          <Icon name={name} />
          <code>{name}</code>
        </span>
      ))}
    </div>
  );
}

Which component uses which icon​

Use the same icon for the same meaning, so people learn it once.

MeansIconUsed by
SitehomeLocationPath
Floorstairs_2LocationPath
Spacedoor_frontLocationPath
Device (Hub or Module)tv_genLocationPath
TemperaturethermostatSensorLabel
Humidityhumidity_midSensorLabel
Illuminancelight_modeSensorLabel
CO₂co2SensorLabel
VOCairwaveSensorLabel
PM2.5grainSensorLabel
LoadingrefreshReadingValue
Disconnectedlink_offReadingValue
FaulterrorDeviceFaultStatus

The other icons in the set aren't used by a component yet.

Illuminance uses light_mode (a sun), not lightbulb, because a bulb looks like a light you can switch, and the kit has no lights to switch.

Sizes​

Use the size prop. The default is md.

sizeSizeUse it next to
xs16pxSmall text (caption, 12px)
sm20px14px text
md24px16px text. Default.
lg32pxLarge numbers, like a lg ReadingValue

The icons are drawn on a 24px grid, so 20, 24 and 32px look sharpest. 16px is for small text, where 20px is too big.

Loading…
Live editor
<div
  style={{ display: "flex", alignItems: "center", gap: "var(--shk-space-4)" }}
>
  <Icon name="thermostat" size="xs" />
  <Icon name="thermostat" size="sm" />
  <Icon name="thermostat" size="md" />
  <Icon name="thermostat" size="lg" />
</div>

Colour​

An icon takes the text colour around it, so it always matches the text next to it. To change its colour, change the text colour of its parent:

Loading…
Live editor
<div style={{ display: "flex", gap: "var(--shk-space-4)" }}>
  <span style={{ color: "var(--shk-color-text-primary)" }}>
    <Icon name="error" />
  </span>
  <span style={{ color: "var(--shk-color-text-secondary)" }}>
    <Icon name="error" />
  </span>
  <span style={{ color: "var(--shk-status-danger-fg)" }}>
    <Icon name="error" />
  </span>
</div>

Screen readers​

Every icon is either decorative or meaningful:

  • Decorative, when text next to it already says the same thing, like the thermostat next to "Temperature". Leave label out: screen readers skip the icon.
  • Meaningful, when the icon is the only thing that says it, like a disconnected icon in place of a value. Pass a label: screen readers read it.
Loading…
Live editor
<StackLayout gap="sm">
  {/* Decorative: the text says the same thing */}
  <span
    style={{ display: "flex", alignItems: "center", gap: "var(--shk-space-1)" }}
  >
    <Icon name="thermostat" size="sm" />
    Temperature
  </span>
  {/* Meaningful: the icon is all there is */}
  <Icon name="link_off" label="Disconnected" />
</StackLayout>

Don't use an icon on its own as a button: there's no icon button in the kit yet. Use a Button with text.

Props​

PropTypeDefaultDescription
nameIconName–Required. Which icon to show. Only the names in the icon set work.
size"xs" | "sm" | "md" | "lg""md"16, 20, 24 or 32px.
labelstringnoneWhat the icon means, read by screen readers, like "Disconnected". Leave it out when the icon is decorative.

The types IconProps, IconName and IconSize are exported too:

import type { IconName, IconProps, IconSize } from "@detriz-sh-kit/ui";

Icons in a row​

An icon never gets squashed in a row: it keeps its size, and the text next to it shrinks instead. That's why long names in SensorLabel and LocationPath end with … while their icons stay whole.

Missing an icon?​

The set is fixed, so every screen uses icons that have been checked together. If you need an icon that isn't in the set, ask for it to be added to the kit rather than mixing in icons from somewhere else.