LocationPath
Shows where a Device is: its Site, Floor, Space and the Device itself, each with its own icon. Use it so people know which Device they are looking at without opening anything.
<LocationPath siteName="My flat" floorName="Level 2" spaceName="Bedroom" deviceName="Climate Module" />
The examples on this page are live. Change the code and the result updates as you type.
Import
import { LocationPath } from "@detriz-sh-kit/ui";
The component needs the kit's styles. Load them once, at the root of your app:
import "@detriz-sh-kit/tokens/tokens.css";
import "@detriz-sh-kit/ui/styles.css";
See Installation for how to install the packages.
Basic usage
Pass the names you want to show:
import { LocationPath } from "@detriz-sh-kit/ui";
<LocationPath
siteName="My flat"
floorName="Level 2"
spaceName="Bedroom"
deviceName="Climate Module"
/>;
The examples below leave out the import line. In your app, you need it.
When to use it
Use LocationPath in:
- card headers, to say which Device the card is about
- list rows, to tell Devices with the same name apart
- detail views, to show the full location
Don't use it for:
- Navigation. LocationPath is read-only. Clicking a part does nothing.
- Device Status. The path is a fixed fact and doesn't change when a Device disconnects or has a Fault. Put
DeviceConnectionStatus,DevicePairingStatusorDeviceFaultStatusnext to it instead. - Sensors and Metrics. A Sensor is not a Device and has no location of its own. Use
SensorLabelto say what a Sensor measures.
Layouts
Use the layout prop to choose how the parts are arranged. The default is inline.
| Layout | Looks like | Use it when |
|---|---|---|
inline | All parts on one line. | Card headers, list rows. |
grid | Two parts per row. | Narrow cards that still need it all. |
stack | One part per line. | Side panels, detail views. |
Inline
<LocationPath siteName="My flat" floorName="Level 2" spaceName="Bedroom" deviceName="Climate Module" />
Grid
<LocationPath layout="grid" siteName="My flat" floorName="Level 2" spaceName="Bedroom" deviceName="Climate Module" />
Each column is as wide as its longest name. If a part is left out, the parts after it move up to fill the gap.
Stack
<LocationPath layout="stack" siteName="My flat" floorName="Level 2" spaceName="Bedroom" deviceName="Climate Module" />
Showing only some parts
Every part is optional. A part is shown only when you pass its name, and an empty part is never shown. The order is always the same: Site, Floor, Space, Device.
Pass only what the screen needs. For example, if a list is already grouped by Site and Space, each row only needs the Device name.
<StackLayout> {/* No Floor */} <LocationPath siteName="My flat" spaceName="Bedroom" deviceName="Climate Module" /> {/* Up to Space, no Device */} <LocationPath siteName="My flat" floorName="Level 2" spaceName="Bedroom" /> {/* A row in a list already grouped by Site and Space */} <LocationPath deviceName="Climate Module" /> </StackLayout>
If you pass no names at all, LocationPath renders nothing.
Mapping your data
Each prop matches a term from the Glossary. Pass the name of each one.
| Prop | Domain term | Example |
|---|---|---|
siteName | Site | My flat |
floorName | Floor | Level 2 |
spaceName | Space | Bedroom |
deviceName | Hub or Module | Climate Module |
A few rules from the domain model:
- Floor: only some Sites use Floors. If yours doesn't, leave
floorNameout. - Hub: a Hub has no Space until it is Paired. Leave
spaceNameout until then. - Module: a Module has no Space of its own. Pass the Space of the Hub it is plugged into.
- Space: pass the Space's own name ("Anna's room"), not its Space Type ("Bedroom").
Props
| Prop | Type | Default | Description |
|---|---|---|---|
siteName | string | none | Name of the Site, the top of the path. Leave out if the screen already shows it. |
floorName | string | none | Name of the Floor, for example "Level 2". Leave out if the Site doesn't use Floors. |
spaceName | string | none | Name of the Space. Leave out if the Device has no Space yet. |
deviceName | string | none | Name of the Device (Hub or Module) the path points to. |
layout | "inline" | "grid" | "stack" | "inline" | How the parts are arranged. |
The types LocationPathProps and LocationPathLayout are exported too:
import type { LocationPathProps, LocationPathLayout } from "@detriz-sh-kit/ui";
Long names
LocationPath never wraps or overflows its container. When there isn't enough room, long names are shortened with … while short names stay whole. The full name shows as a tooltip when you hover over it.
<div style={{ maxWidth: 320 }}> <LocationPath siteName="My flat" floorName="Level 2" spaceName="Anna's bedroom on the top floor" deviceName="Climate Module by the window" /> </div>
Accessibility
What you get without doing anything:
- The path is an ordered list (
<ol>) labelled "Location", because the order has meaning. - Icons are hidden from screen readers. Instead, each name gets a hidden prefix, so screen readers say "Site: My flat", "Floor: Level 2", "Space: Bedroom" and "Device: Climate Module".
- The text colour meets the WCAG AA contrast ratio (4.5:1) on light backgrounds.
What's up to you:
- Don't add your own "Location:" heading or label right next to it. Screen readers already announce one.
- Check the contrast if you place it on a dark or coloured background.
Styling
LocationPath uses the kit's design tokens (CSS variables starting with --shk-):
| What | Token |
|---|---|
| Text and icon colour | --shk-color-text-primary |
| Text style | --shk-typography-caption-* (12px) |
| Gap between icon and name | --shk-space-1 (4px) |
Gap between parts (inline, grid) | --shk-space-4 (16px) |
Gap between parts (stack) | --shk-space-2 (8px) |
To change how it looks, set a token on a parent element. The change applies to everything inside that element, not only LocationPath:
.my-card-header {
--shk-color-text-primary: var(--shk-palette-gray-700);
}
Related components
DeviceConnectionStatus: shows whether the Device is Connecting, Connected, Stale or Disconnected.DevicePairingStatus: shows whether the Device is Paired.DeviceFaultStatus: shows a Device's Fault.SensorLabel: says what a Sensor measures. Sits well next to LocationPath in a card header.