Sensor cards are built by composition, from three components: CwLocationCard owns the location
shell, CwSensorCard owns a single expandable sensor panel, and CwDataList renders the detail rows. Nested cards stay reactive when the parent
updates their props, and the location header rolls up the status of every sensor inside it.
Interactive
One location shell, one sensor panel, one data list
The outer location card reacts to the nested sensor status automatically. The sensor
panel exposes expand/collapse and freshness callbacks without taking ownership of the
input data.
Sensor freshness: no timer
Row freshness map: {}
Greenhouse A
Loading
Details
Temperature
-22.93°C
Humidity
79.61%
Last Update
ago
Error state
Surface a hardware fault with the hasError attribute
Setting hasError hides the normal primary/secondary readings and shows a
pulsing red error badge in their place, so a fault is impossible to miss. The string you
pass becomes the badge text — pass a localized message (true falls back to a
generic SENSOR ERROR).
Greenhouse C
Loading
Details
Temperature
-5.10°C
Humidity
88.00%
CwDataList
The extracted detail-list component
Use CwDataList for the standard sensor detail rows inside an expanded
panel, or anywhere else you need the same metadata layout.
Sensor detail rows
Rendered with CwDataList
Temperature
22.40°C
Humidity
67.30%
Last Update
ago
CwLocationCard · aggregate status
Nested sensor panels roll up to the location header
The location shell now derives its own header status from the sensor cards rendered
inside it. Mixed sensor states resolve to warning.
All online
Research Lab
Online
Details
Temperature
21.50°C
Humidity
58.20%
Last Update
ago
Details
Temperature
19.80°C
Humidity
62.10%
Last Update
ago
Mixed online and offline
Soil Station Array
Online
Details
Temperature
14.30°C
Humidity
38.90%
Last Update
ago
Details
Temperature
15.25°C
Humidity
41.20%
Last Update
ago
Details
Temperature
13.70°C
Humidity
44.50%
Last Update
ago
All offline
Warehouse B (down)
Online
Details
Temperature
0.00°C
Last Update
ago
Details
Temperature
0.00°C
Last Update
ago
All loading
Provisioning Bay
Loading
Details
Temperature
0.00°C
Details
Temperature
0.00°C
Custom rows
Override the default rows when the sensor needs richer metadata
Weather stations and tank monitors often need row labels that do not map cleanly to
the default temperature and humidity assumptions. That is where passing explicit detailRows into CwDataList pays off.
Weather Station Alpha
Loading
Details
Temperature
22.40°C
Humidity
67.30%
🌧️Rain Amount
3.20mm
💨Wind Speed
12.50km/h
☀️Lux Level
48500lx
🔵Air Pressure
1,013.25hPa
⚡Relay State
On
Last Update
ago
Tank Monitor
Loading
Details
Water Level
74.50%
Last Update
ago
Collapsed matrix
Compact cards and the empty state
Short sensor panels stay compact by default, and an empty location card now stands on
its own without pretending to be a sensor panel.
Field Station 1
Loading
Details
Temperature
24.50°C
Humidity
65.20%
Last Update
ago
Warehouse B
Loading
Details
Temperature
-5.10°C
Humidity
88.00%
Last Update
ago
Rooftop Array
Loading
Details
Temperature
0.00°C
Humidity
0.00%
Lab Freezer
Loading
Details
Temperature
-18.25°C
Humidity
72.40%
Last Update
ago
New Location (unassigned)
Loading
No sensors assigned
States & localisation
Loading, stale readings and translated labels
loading shows skeleton readings. When lastSeenAt is older than expireAfterMinutes, the readings dim and a “Last seen … ago” line appears.
Every visible string can be replaced through labels.
CwLocationCard, CwSensorCard, and CwDataList now split the old monolithic sensor-card API into three focused pieces. Compose them in markup so location state, sensor state, and detail rows stay reactive without pushing a devices array into one component.
How to think about it
Start with the location shellWrap each sensor stack in `CwLocationCard`. The location header derives aggregate status from nested `CwSensorCard` children, but you can still pass a fallback `status` for empty locations.
Render one sensor per CwSensorCardEach expandable panel now owns exactly one sensor. Pass the readings and freshness props directly to that card, and use `defaultExpanded`, `storageKey`, or `bind:open` when you need expand-state control.
Feed the expanded body with CwDataListPass `rows` into `CwDataList` for the standard detail layout. Use explicit row arrays when the sensor needs custom metadata, or fall back to `buildCwSensorCardDetailRows(sensor)` for common temperature and humidity cases.
Bind freshness where you need itUse `onNavigate` on the location shell, `onExpand`, `onCollapse`, `onExpire`, and `bind:withinTimeout` on the sensor card, and `bind:rowWithinTimeoutMap` on the data list when the host app needs row-level freshness state.
Composition props
The intended structure is `CwLocationCard` -> `CwSensorCard` -> `CwDataList`. Use `CwCardDataRowItem` directly only when you need row-level control outside the shared list wrapper.
API
Type
Details
CwLocationCard.title
Default: Location
string
Location or site label shown in the outer shell header.
CwLocationCard.status
Default: loading
CwStatusDotStatus
Fallback location status used when no nested sensor cards are registered.
CwLocationCard.onNavigate
(target: string) => void
Called from the location header action button.
CwSensorCard.label
string
Sensor or device label shown in the expandable panel header.
CwSensorCard.status
Default: loading
CwStatusDotStatus
Base sensor status before freshness overrides are applied.