Layout blocks

Layout blocks

A small tile can only hold so much. Layout blocks let a widget hold more by folding some of it away, putting some of it behind a tab, or placing a picture exactly where you want it. They are components like any other, so you write them in the template.

Sections that fold

hd-section is a part of the widget that opens and closes under a heading. While it is closed it can show a short summary next to the heading.

<hd-section heading="Details" summary="{{ cap.measure_humidity.text }} %">  <p>{{ device.name }}</p>  <p>CO₂ {{ cap.measure_co2.text }} {{ cap.measure_co2.unit }}</p></hd-section>
AttributeWhat it does
headingWhat the section is called. Required.
iconAn icon in front of the heading.
summaryA short line beside the heading while the section is closed.
opentrue for open, false for closed. Empty leaves it to start.
startclosed (the default) or open, until something is remembered.
variantplain is a heading over a hairline, and card is a raised card.

On its own the section folds, but it starts over every time the widget is drawn anew. To keep it open or closed, bind open to the widget’s state and store each change. The section tells you the new value as event.value:

<hd-section  heading="Details"  open="{{ state.details }}"  data-hd-on-change="setState('details', event.value)">  …</hd-section>

State is kept per tile on the screen, so a section a person opened is still open after a reload.

Tabs

hd-tabs holds panes, hd-tab, of which one shows at a time. The person using the tile switches by tapping the tab bar, swiping across the pane, or with the arrow keys.

<hd-tabs label="Period">  <hd-tab name="today" label="Today"><p>Today</p></hd-tab>  <hd-tab name="week" label="Week"><p>This week</p></hd-tab></hd-tabs>

hd-tab goes directly inside hd-tabs, with a name (what selected calls it) and a label (the text on its tab), and optionally an icon.

AttributeWhat it does
selectedThe name of the tab to show. Empty or unknown shows the first.
labelWhat the tabs choose between, for screen readers.
variantThe tab bar: pill, underline or dots.
placementtop or bottom.
swipeWhether swiping across the pane changes tab. On by default.

Remember the chosen tab the same way as a section:

<hd-tabs  label="Period"  selected="{{ state.period }}"  data-hd-on-change="setState('period', event.value)">  …</hd-tabs>

Swiping across a tab never turns the page of a wall panel.

This widget puts the temperature on one tab and the air on another:

tabs.liquid
<hd-tabs label="Room" selected="{{ state.tab }}" data-hd-on-change="setState('tab', event.value)">  <hd-tab name="now" label="Now">    <p class="big">{{ cap.measure_temperature.value | temp: 1 }}</p>    <p class="sub">{{ device.name }}</p>  </hd-tab>  <hd-tab name="air" label="Air">    {% render 'value-row', label: 'Humidity', value: cap.measure_humidity.text, unit: cap.measure_humidity.unit %}    {% render 'value-row', label: 'CO₂', value: cap.measure_co2.text, unit: cap.measure_co2.unit %}  </hd-tab></hd-tabs>

Placing an icon or a picture

hd-place puts what is inside it at a spot of its own, on top of or behind the rest of the widget. What is inside fills the box.

<hd-place at="top-right" size="large">  <hd-icon name="device.light"></hd-icon></hd-place>

The box is placed relative to the widget, or to the nearest element that has position: relative.

AttributeWhat it does
atOne of nine spots: top-left, top-center, top-right, middle-left and so on. It sets x, y and anchor at once.
x, yA place from 0 to 100, across and down. They win over at.
anchorWhich point of the box sits at x, y. The same as at, else the middle.
sizesmall, medium, large or huge (24, 40, 64 or 96 pixels), or a width: 40% of the widget or 56px.
ratioWidth to height of the box: 1, 1.5, 4/3 or 16/9.
layerfront is over the content. back is behind it, and then it takes no taps.

Use layer="back" for a big faded icon behind the text:

<hd-place at="bottom-right" size="60%" layer="back">  <hd-icon name="device.thermostat" weight="duotone"></hd-icon></hd-place>

A picture works the same way, with hd-image inside the place: a device’s own picture, such as a camera’s snapshot, or a picture at a web address. The components reference lists the attributes of hd-image.

Items that follow the tile’s layout

Some widgets show a list of items: buttons, readings, rooms. A tile’s owner can say in the Style panel where those items sit, whether they stay at one side or share the width. That choice reaches your style as a few CSS variables, and each one is unset until the tile says something, so always give it your own default:

VariableWhat it saysValues
--hd-item-alignWhere the content sits up and downflex-start, center, flex-end
--hd-item-justifyWhere the content sits sidewaysflex-start, center, flex-end, stretch
--hd-item-repeatSet when items move sideways or share the width: unused grid columns goauto-fit
--hd-item-trackSet with --hd-item-repeat: fold to content to move, or split the widthmax-content, 1fr
--hd-item-growSet while the items share the width: items in a row grow1

A grid of items that obeys them looks like this:

.items {  display: grid;  grid-template-columns: repeat(    var(--hd-item-repeat, auto-fill),    minmax(120px, var(--hd-item-track, 1fr))  );  justify-content: var(--hd-item-justify, flex-start);}.item {  flex-grow: var(--hd-item-grow, 0);}

Which of the directions the Style panel offers for your widget is up to its manifest’s align. The widget you started from decides it, and the manifest reference shows the field. The style variables reference has the same variables.

Layouts the tile’s owner arranges

The custom tile, one of the built-in widgets, lets its owner fold the values it shows into sections and tabs and place pictures, without any template. It does so with a setting of the kind A layout that arranges a Values setting. Your own widgets can declare the same two settings, and draw what the layout setting gives with the blocks on this page. The settings reference describes the layout kind.