Summary
A summary presents a clear summarised output of values to the user.
<div class="ons-summary">
<div id="turnover" class="ons-summary__group">
<h2 class="ons-summary__group-title">Turnover</h2>
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
<th>Question</th>
<th>Answer given</th>
<th>Change answer</th>
</tr>
</thead>
<tbody id="sales-dates-row" class="ons-summary__item">
<tr id="sales-dates" class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">What are the dates of the sales period you are reporting for? </div>
</td>
<td class="ons-summary__values">
1 January 2015 to 2 February 2017
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
<tbody id="sales-value-row" class="ons-summary__item">
<tr id="sales-value" class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">For the period 1 January 2015 to 2 February 2017, what was the value of your total turnover, excluding VAT? </div>
</td>
<td class="ons-summary__values">
£180,440
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
<tbody id="sales-reasons-row" class="ons-summary__item">
<tr id="sales-reasons" class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Please indicate the reasons for any changes in the total turnover </div>
</td>
<td class="ons-summary__values">
<ul class="ons-u-mb-no">
<li>
Change in level of business activity
</li>
<li>
Special/calendar events
<ul class="ons-u-mb-no">
<li>Some other value</li>
</ul>
</li>
</ul>
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
<tbody id="sales-detail-row" class="ons-summary__item">
<tr id="sales-detail" class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Please describe the changes in total turnover in more detail </div>
</td>
<td class="ons-summary__values">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
{% from "components/summary/_macro.njk" import onsSummary %}
{{
onsSummary({
"summaries": [
{
"groups": [
{
"id": "turnover",
"groupTitle": "Turnover",
"headers":["Question", "Answer given", "Change answer"],
"rows": [
{
"id": "sales-dates-row",
"rowTitle": "What are the dates of the sales period you are reporting for?",
"rowItems": [
{
"id": "sales-dates",
"valueList": [
{
"text": "1 January 2015 to 2 February 2017"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "For the period 1 January 2015 to 2 February 2017, what was the value of your total turnover, excluding VAT?",
"id": "sales-value-row",
"rowItems": [
{
"id": "sales-value",
"valueList": [
{
"text": "£180,440"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
},
{
"id": "sales-reasons-row",
"rowTitle": "Please indicate the reasons for any changes in the total turnover",
"rowItems": [
{
"id": "sales-reasons",
"valueList": [
{
"text": "Change in level of business activity"
},
{
"text": "Special/calendar events",
"other": "Some other value"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
},
{
"id": "sales-detail-row",
"rowTitle": "Please describe the changes in total turnover in more detail",
"rowItems": [
{
"id": "sales-detail",
"valueList": [
{
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
}
]
}
]
}
]
})
}}
{% macro onsSummary(params) %}
{% set className = "ons-summary" %}
{% set titleSize = "2" %}
{% if params.classes is defined and params.classes %}
{% set className = className + " " + params.classes %}
{% endif %}
{% if params.hub is defined and params.hub %}
{% set className = className + " ons-summary--hub" %}
{% endif %}
<div class="{{ className }}">
{% for summary in params.summaries %}
{% if summary.summaryTitle is defined and summary.summaryTitle %}
<h2 class="ons-summary__title ons-u-mb-m">{{ summary.summaryTitle }}</h2>
{% set titleSize = "3" %}
{% endif %}
{% for group in summary.groups %}
<div {% if group.id is defined and group.id %}id="{{ group.id }}" {% endif %} class="ons-summary__group">
{% if group.groupTitle is defined and group.groupTitle %}
<h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
{% endif %}
{% if group.headers is defined and group.headers and group.rows is defined and group.rows %}
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
{% for header in group.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
{% for row in (group.rows if group.rows is iterable else group.rows.items()) %}
{% set itemClass = "" %}
{% if row.error is defined and row.error %} {% set itemClass = " ons-summary__item--error" %}{% endif %}
{% if row.total is defined and row.total %} {% set itemClass = itemClass + " ons-summary__item--total" %}{% endif %}
<tbody {% if row.id is defined and row.id %}id="{{ row.id }}" {% endif %}class="ons-summary__item{{ itemClass }}">
{% if row.errorMessage is defined and row.errorMessage or (row.rowItems | length > 1 and row.rowTitle) %}
<tr class="ons-summary__row">
<th colspan="3" class="ons-summary__row-title ons-u-fs-r">{{ row.errorMessage or row.rowTitle }}</th>
</tr>
{% endif %}
{% for rowItem in row.rowItems %}
<tr {% if rowItem.id is defined and rowItem.id %}id="{{ rowItem.id }}" {% endif %}class="ons-summary__row{{ " ons-summary__row--has-values" if rowItem.valueList else "" }}">
<td
class="ons-summary__item-title"
{% if rowItem.rowTitleAttributes is defined and rowItem.rowTitleAttributes %}{% for attribute, value in (rowItem.rowTitleAttributes.items() if rowItem.rowTitleAttributes is mapping and rowItem.rowTitleAttributes.items else rowItem.rowTitleAttributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.iconType is defined and rowItem.iconType %}
{% from "components/icons/_macro.njk" import onsIcon %}
<span class="ons-summary__item-title-icon {% if rowItem.iconType == 'check' %} ons-summary__item-title-icon--check{% endif %}">
{{
onsIcon({
"iconType": rowItem.iconType
})
}}
</span>
{% endif %}
<div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }} {{ hasIcons }}</div>
{# Render section status for mobile if is hub #}
{% if params.hub is defined and params.hub and rowItem.valueList is defined and rowItem.valueList %}
<span class="ons-u-d-no@s ons-u-fs-r"> — {{ rowItem.valueList[0].text | safe }}</span>
{% endif %}
</td>
{% if rowItem.valueList is defined and rowItem.valueList %}
<td
class="ons-summary__values"
{% if rowItem.actions == null %} colspan="2"{% endif %}
{% if rowItem.attributes is defined and rowItem.attributes %}{% for attribute, value in (rowItem.attributes.items() if rowItem.attributes is mapping and rowItem.attributes.items else rowItem.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.valueList | length == 1 %}
{{ rowItem.valueList[0].text | safe }}
{% if rowItem.valueList[0].other is defined and rowItem.valueList[0].other or rowItem.valueList[0].other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ rowItem.valueList[0].other | safe }}</li>
</ul>
{% endif %}
{% else %}
<ul class="ons-u-mb-no">
{% for value in (rowItem.valueList if rowItem.valueList is iterable else rowItem.valueList.items()) %}
<li>
{{ value.text | safe }}
{% if value.other is defined and value.other or value.other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ value.other | safe }}</li>
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endif %}
{% if rowItem.actions is defined and rowItem.actions %}
<td class="ons-summary__actions">
{% for action in (rowItem.actions if rowItem.actions is iterable else rowItem.actions.items()) %}
{% if loop.index > 1 %}<span class="ons-summary__spacer"></span>{% endif %}
<a
href="{{ action.url }}"
class="ons-summary__button"
{% if action.ariaLabel is defined and action.ariaLabel %} aria-label="{{ action.ariaLabel }}"{% endif %}
{% if action.attributes is defined and action.attributes %}{% for attribute, value in (action.attributes.items() if action.attributes is mapping and action.attributes.items else action.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>{{ action.text }}</a>
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% elif group.placeholderText is defined and group.placeholderText %}
{{ group.placeholderText }}
{% endif %}
{% if group.summaryLink is defined and group.summaryLink %}
<div class="{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %}ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
<a {% if group.summaryLink.attributes is defined and group.summaryLink.attributes %}{% for attribute, value in (group.summaryLink.attributes.items() if group.summaryLink.attributes is mapping and group.summaryLink.attributes.items else group.summaryLink.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %} href="{{ group.summaryLink.url }}">{{ group.summaryLink.text }}</a>
</div>
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endmacro %}
@use 'sass:math';
$summary-row-spacing: 1rem;
$summary-col-spacing: 1rem;
$hub-row-spacing: 1.3rem;
.ons-summary {
&__items {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
+ .ons-summary__group-title {
margin-top: 1.5rem;
}
}
&__item {
line-height: 1.4;
&:not(:last-child),
&:nth-of-type(1) {
border-bottom: 1px solid $color-borders;
}
&--total {
@extend .ons-u-fs-m;
border-width: 2px;
font-weight: 700;
}
&--error {
background: $color-errors-tint;
border-left: 8px solid $color-errors;
}
}
&__row-title {
padding: $summary-row-spacing 0;
text-align: left;
}
&__item-title,
&__values,
&__actions {
hyphens: manual;
overflow-wrap: break-word;
padding: 0 0 $summary-row-spacing;
vertical-align: top;
word-wrap: break-word;
}
&__item-title {
padding-top: $summary-row-spacing;
position: relative;
&--text {
display: block;
overflow: hidden;
padding-left: 2rem;
}
&-icon {
left: 0;
position: absolute;
text-align: center;
&--check .ons-svg-icon {
fill: $color-leaf-green !important;
}
}
}
&__actions {
white-space: nowrap;
}
&__spacer {
background: $color-black;
display: inline-block;
height: 1rem;
margin: 0 0.25rem;
vertical-align: middle;
width: 1px;
}
// Item Modifiers
&__item--total & {
&__values {
@extend .ons-u-fs-m;
}
}
&__item--error & {
&__row-title {
color: $color-errors;
font-weight: 700;
padding: $summary-row-spacing $summary-col-spacing;
}
&__item-title,
&__values,
&__actions {
padding-left: $summary-col-spacing;
padding-right: $summary-col-spacing;
@include mq('s') {
padding-left: math.div($summary-col-spacing, 2);
padding-right: math.div($summary-col-spacing, 2);
&:first-child {
padding-left: $summary-col-spacing;
}
&:last-child {
padding-right: $summary-col-spacing;
}
}
}
}
// Modifiers
&--hub & {
&__actions {
padding: 0 0 $hub-row-spacing;
}
&__item-title {
@extend .ons-u-fs-r--b;
padding-top: $hub-row-spacing;
}
}
&:not(&--hub) & {
&__values {
@extend .ons-u-fs-r--b;
}
}
// Breakpoints
@include mq(xxs, s, none, '<') {
&__item-title,
&__values,
&__actions {
display: block;
}
&--hub & {
&__values {
display: none;
}
}
}
@include mq(s) {
&__item-title,
&__values,
&__actions {
padding-top: $summary-row-spacing;
vertical-align: top;
&:not(:last-child) {
padding-right: $summary-col-spacing;
}
}
&__actions {
text-align: right;
}
&__row--has-values & {
&__item-title,
&__values {
width: 50%;
}
}
&--hub & {
&__item-title,
&__values,
&__actions {
padding-top: $hub-row-spacing;
}
}
}
}
When to use this component
Display a summary on a page after the user completes a section or full questionnaire, to let them check and confirm their answers.
How to use this component
The summary should provide users with a direct link back to the question(s) they have answered, allowing them to change their answer, then return to the summary to complete or continue their questionnaire.
The summary can contain multiple question and answer types, and will adapt its layout depending on the length of the strings.
The component contains a summaries
key which can contain multiple summary groups
. This allows for multiple summaries to be displayed. Each group in groups
can have an optional groupTitle
which provides a heading for the rows
and renders a h2
.
This provides flexibility to allow for simple and complex summaries to be created within one instance of the onsSummary
macro.
Accessibility
The summary component is made accessible by using the following aria
attributes which are attached on domready
via JavaScript:
Element | ARIA attribute | Description |
---|---|---|
.ons-summary__button
|
aria-label="{ariaLabel}"
|
Increases verbosity of the element's label |
Headers
The parameter headers
must be provided with an array of values, so screen reader users can understand the purpose of each column in the summary table. For example, for a 2-column summary showing the questions and answers given in a questionnaire should you should set: "headers": ["Question", "Answer given"]
.
Variants
Summary without action
A summary of an answer the user cannot directly change, due to it being automatically calculated.
<div class="ons-summary">
<div class="ons-summary__group">
<h2 class="ons-summary__group-title">Turnover</h2>
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
<th>Question</th>
<th>Answer given</th>
</tr>
</thead>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">What are the dates of the sales period you are reporting for? </div>
</td>
<td class="ons-summary__values" colspan="2">
01 January 2015 to 02 February 2017
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Total turnover </div>
</td>
<td class="ons-summary__values" colspan="2">
£234,000.00
</td>
</tr>
</tbody>
</table>
</div>
</div>
{% from "components/summary/_macro.njk" import onsSummary %}
{{
onsSummary({
"summaries": [
{
"groups": [
{
"groupTitle": "Turnover",
"headers":["Question", "Answer given"],
"rows": [
{
"rowTitle": "What are the dates of the sales period you are reporting for?",
"rowItems": [
{
"valueList": [
{
"text": "01 January 2015 to 02 February 2017"
}
]
}
]
},
{
"rowTitle": "Total turnover",
"rowItems": [
{
"valueList": [
{
"text": "£234,000.00"
}
]
}
]
}
]
}
]
}
]
})
}}
{% macro onsSummary(params) %}
{% set className = "ons-summary" %}
{% set titleSize = "2" %}
{% if params.classes is defined and params.classes %}
{% set className = className + " " + params.classes %}
{% endif %}
{% if params.hub is defined and params.hub %}
{% set className = className + " ons-summary--hub" %}
{% endif %}
<div class="{{ className }}">
{% for summary in params.summaries %}
{% if summary.summaryTitle is defined and summary.summaryTitle %}
<h2 class="ons-summary__title ons-u-mb-m">{{ summary.summaryTitle }}</h2>
{% set titleSize = "3" %}
{% endif %}
{% for group in summary.groups %}
<div {% if group.id is defined and group.id %}id="{{ group.id }}" {% endif %} class="ons-summary__group">
{% if group.groupTitle is defined and group.groupTitle %}
<h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
{% endif %}
{% if group.headers is defined and group.headers and group.rows is defined and group.rows %}
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
{% for header in group.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
{% for row in (group.rows if group.rows is iterable else group.rows.items()) %}
{% set itemClass = "" %}
{% if row.error is defined and row.error %} {% set itemClass = " ons-summary__item--error" %}{% endif %}
{% if row.total is defined and row.total %} {% set itemClass = itemClass + " ons-summary__item--total" %}{% endif %}
<tbody {% if row.id is defined and row.id %}id="{{ row.id }}" {% endif %}class="ons-summary__item{{ itemClass }}">
{% if row.errorMessage is defined and row.errorMessage or (row.rowItems | length > 1 and row.rowTitle) %}
<tr class="ons-summary__row">
<th colspan="3" class="ons-summary__row-title ons-u-fs-r">{{ row.errorMessage or row.rowTitle }}</th>
</tr>
{% endif %}
{% for rowItem in row.rowItems %}
<tr {% if rowItem.id is defined and rowItem.id %}id="{{ rowItem.id }}" {% endif %}class="ons-summary__row{{ " ons-summary__row--has-values" if rowItem.valueList else "" }}">
<td
class="ons-summary__item-title"
{% if rowItem.rowTitleAttributes is defined and rowItem.rowTitleAttributes %}{% for attribute, value in (rowItem.rowTitleAttributes.items() if rowItem.rowTitleAttributes is mapping and rowItem.rowTitleAttributes.items else rowItem.rowTitleAttributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.iconType is defined and rowItem.iconType %}
{% from "components/icons/_macro.njk" import onsIcon %}
<span class="ons-summary__item-title-icon {% if rowItem.iconType == 'check' %} ons-summary__item-title-icon--check{% endif %}">
{{
onsIcon({
"iconType": rowItem.iconType
})
}}
</span>
{% endif %}
<div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }} {{ hasIcons }}</div>
{# Render section status for mobile if is hub #}
{% if params.hub is defined and params.hub and rowItem.valueList is defined and rowItem.valueList %}
<span class="ons-u-d-no@s ons-u-fs-r"> — {{ rowItem.valueList[0].text | safe }}</span>
{% endif %}
</td>
{% if rowItem.valueList is defined and rowItem.valueList %}
<td
class="ons-summary__values"
{% if rowItem.actions == null %} colspan="2"{% endif %}
{% if rowItem.attributes is defined and rowItem.attributes %}{% for attribute, value in (rowItem.attributes.items() if rowItem.attributes is mapping and rowItem.attributes.items else rowItem.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.valueList | length == 1 %}
{{ rowItem.valueList[0].text | safe }}
{% if rowItem.valueList[0].other is defined and rowItem.valueList[0].other or rowItem.valueList[0].other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ rowItem.valueList[0].other | safe }}</li>
</ul>
{% endif %}
{% else %}
<ul class="ons-u-mb-no">
{% for value in (rowItem.valueList if rowItem.valueList is iterable else rowItem.valueList.items()) %}
<li>
{{ value.text | safe }}
{% if value.other is defined and value.other or value.other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ value.other | safe }}</li>
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endif %}
{% if rowItem.actions is defined and rowItem.actions %}
<td class="ons-summary__actions">
{% for action in (rowItem.actions if rowItem.actions is iterable else rowItem.actions.items()) %}
{% if loop.index > 1 %}<span class="ons-summary__spacer"></span>{% endif %}
<a
href="{{ action.url }}"
class="ons-summary__button"
{% if action.ariaLabel is defined and action.ariaLabel %} aria-label="{{ action.ariaLabel }}"{% endif %}
{% if action.attributes is defined and action.attributes %}{% for attribute, value in (action.attributes.items() if action.attributes is mapping and action.attributes.items else action.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>{{ action.text }}</a>
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% elif group.placeholderText is defined and group.placeholderText %}
{{ group.placeholderText }}
{% endif %}
{% if group.summaryLink is defined and group.summaryLink %}
<div class="{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %}ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
<a {% if group.summaryLink.attributes is defined and group.summaryLink.attributes %}{% for attribute, value in (group.summaryLink.attributes.items() if group.summaryLink.attributes is mapping and group.summaryLink.attributes.items else group.summaryLink.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %} href="{{ group.summaryLink.url }}">{{ group.summaryLink.text }}</a>
</div>
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endmacro %}
@use 'sass:math';
$summary-row-spacing: 1rem;
$summary-col-spacing: 1rem;
$hub-row-spacing: 1.3rem;
.ons-summary {
&__items {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
+ .ons-summary__group-title {
margin-top: 1.5rem;
}
}
&__item {
line-height: 1.4;
&:not(:last-child),
&:nth-of-type(1) {
border-bottom: 1px solid $color-borders;
}
&--total {
@extend .ons-u-fs-m;
border-width: 2px;
font-weight: 700;
}
&--error {
background: $color-errors-tint;
border-left: 8px solid $color-errors;
}
}
&__row-title {
padding: $summary-row-spacing 0;
text-align: left;
}
&__item-title,
&__values,
&__actions {
hyphens: manual;
overflow-wrap: break-word;
padding: 0 0 $summary-row-spacing;
vertical-align: top;
word-wrap: break-word;
}
&__item-title {
padding-top: $summary-row-spacing;
position: relative;
&--text {
display: block;
overflow: hidden;
padding-left: 2rem;
}
&-icon {
left: 0;
position: absolute;
text-align: center;
&--check .ons-svg-icon {
fill: $color-leaf-green !important;
}
}
}
&__actions {
white-space: nowrap;
}
&__spacer {
background: $color-black;
display: inline-block;
height: 1rem;
margin: 0 0.25rem;
vertical-align: middle;
width: 1px;
}
// Item Modifiers
&__item--total & {
&__values {
@extend .ons-u-fs-m;
}
}
&__item--error & {
&__row-title {
color: $color-errors;
font-weight: 700;
padding: $summary-row-spacing $summary-col-spacing;
}
&__item-title,
&__values,
&__actions {
padding-left: $summary-col-spacing;
padding-right: $summary-col-spacing;
@include mq('s') {
padding-left: math.div($summary-col-spacing, 2);
padding-right: math.div($summary-col-spacing, 2);
&:first-child {
padding-left: $summary-col-spacing;
}
&:last-child {
padding-right: $summary-col-spacing;
}
}
}
}
// Modifiers
&--hub & {
&__actions {
padding: 0 0 $hub-row-spacing;
}
&__item-title {
@extend .ons-u-fs-r--b;
padding-top: $hub-row-spacing;
}
}
&:not(&--hub) & {
&__values {
@extend .ons-u-fs-r--b;
}
}
// Breakpoints
@include mq(xxs, s, none, '<') {
&__item-title,
&__values,
&__actions {
display: block;
}
&--hub & {
&__values {
display: none;
}
}
}
@include mq(s) {
&__item-title,
&__values,
&__actions {
padding-top: $summary-row-spacing;
vertical-align: top;
&:not(:last-child) {
padding-right: $summary-col-spacing;
}
}
&__actions {
text-align: right;
}
&__row--has-values & {
&__item-title,
&__values {
width: 50%;
}
}
&--hub & {
&__item-title,
&__values,
&__actions {
padding-top: $hub-row-spacing;
}
}
}
}
Grouped
A summary of the answers to multiple questions in a section that are grouped.
In this scenario we can create another heading level for groups
using the summaryTitle
key which renders a h2
and renders the groupTitle
as a h3
.
<h1>Your answers</h1>
<div class="ons-summary">
<h2 class="ons-summary__title ons-u-mb-m">John Doe</h2>
<div class="ons-summary__group">
<h3 class="ons-summary__group-title">Personal details</h3>
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
<th>Question</th>
<th>Answer given</th>
</tr>
</thead>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Are you John Doe? </div>
</td>
<td class="ons-summary__values" colspan="2">
Yes I am
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">What's your date of birth? </div>
</td>
<td class="ons-summary__values" colspan="2">
1 January 1981
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">What is your sex? </div>
</td>
<td class="ons-summary__values" colspan="2">
Male
</td>
</tr>
</tbody>
</table>
</div>
<div class="ons-summary__group">
<h3 class="ons-summary__group-title">Identity and health</h3>
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
<th>Question</th>
<th>Answer given</th>
</tr>
</thead>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">What is your country of birth? </div>
</td>
<td class="ons-summary__values" colspan="2">
England
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">What passports do you hold? </div>
</td>
<td class="ons-summary__values" colspan="2">
United Kingdom
</td>
</tr>
</tbody>
</table>
</div>
<div class="ons-summary__group">
<h3 class="ons-summary__group-title">Qualifications</h3>
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
<th>Question</th>
<th>Answer given</th>
</tr>
</thead>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Have you completed an apprenticeship? </div>
</td>
<td class="ons-summary__values" colspan="2">
Yes
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Have you achieved a GCSE or equivalent qualification? </div>
</td>
<td class="ons-summary__values" colspan="2">
5 GCSEs grades A* to C or 9 to 4
</td>
</tr>
</tbody>
</table>
</div>
</div>
{% from "components/summary/_macro.njk" import onsSummary %}
<h1>Your answers</h1>
{{
onsSummary({
"summaries": [
{
"summaryTitle": "John Doe",
"groups": [
{
"groupTitle": "Personal details",
"headers":["Question", "Answer given"],
"rows": [
{
"rowTitle": "Are you John Doe?",
"rowItems": [
{
"valueList": [
{
"text": "Yes I am"
}
]
}
]
},
{
"rowTitle": "What's your date of birth?",
"rowItems": [
{
"valueList": [
{
"text": "1 January 1981"
}
]
}
]
},
{
"rowTitle": "What is your sex?",
"rowItems": [
{
"valueList": [
{
"text": "Male"
}
]
}
]
}
]
},
{
"groupTitle": "Identity and health",
"headers":["Question", "Answer given"],
"rows": [
{
"rowTitle": "What is your country of birth?",
"rowItems": [
{
"valueList": [
{
"text": "England"
}
]
}
]
},
{
"rowTitle": "What passports do you hold?",
"rowItems": [
{
"valueList": [
{
"text": "United Kingdom"
}
]
}
]
}
]
},
{
"groupTitle": "Qualifications",
"headers":["Question", "Answer given"],
"rows": [
{
"rowTitle": "Have you completed an apprenticeship?",
"rowItems": [
{
"valueList": [
{
"text": "Yes"
}
]
}
]
},
{
"rowTitle": "Have you achieved a GCSE or equivalent qualification?",
"rowItems": [
{
"valueList": [
{
"text": "5 GCSEs grades A* to C or 9 to 4"
}
]
}
]
}
]
}
]
}
]
})
}}
{% macro onsSummary(params) %}
{% set className = "ons-summary" %}
{% set titleSize = "2" %}
{% if params.classes is defined and params.classes %}
{% set className = className + " " + params.classes %}
{% endif %}
{% if params.hub is defined and params.hub %}
{% set className = className + " ons-summary--hub" %}
{% endif %}
<div class="{{ className }}">
{% for summary in params.summaries %}
{% if summary.summaryTitle is defined and summary.summaryTitle %}
<h2 class="ons-summary__title ons-u-mb-m">{{ summary.summaryTitle }}</h2>
{% set titleSize = "3" %}
{% endif %}
{% for group in summary.groups %}
<div {% if group.id is defined and group.id %}id="{{ group.id }}" {% endif %} class="ons-summary__group">
{% if group.groupTitle is defined and group.groupTitle %}
<h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
{% endif %}
{% if group.headers is defined and group.headers and group.rows is defined and group.rows %}
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
{% for header in group.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
{% for row in (group.rows if group.rows is iterable else group.rows.items()) %}
{% set itemClass = "" %}
{% if row.error is defined and row.error %} {% set itemClass = " ons-summary__item--error" %}{% endif %}
{% if row.total is defined and row.total %} {% set itemClass = itemClass + " ons-summary__item--total" %}{% endif %}
<tbody {% if row.id is defined and row.id %}id="{{ row.id }}" {% endif %}class="ons-summary__item{{ itemClass }}">
{% if row.errorMessage is defined and row.errorMessage or (row.rowItems | length > 1 and row.rowTitle) %}
<tr class="ons-summary__row">
<th colspan="3" class="ons-summary__row-title ons-u-fs-r">{{ row.errorMessage or row.rowTitle }}</th>
</tr>
{% endif %}
{% for rowItem in row.rowItems %}
<tr {% if rowItem.id is defined and rowItem.id %}id="{{ rowItem.id }}" {% endif %}class="ons-summary__row{{ " ons-summary__row--has-values" if rowItem.valueList else "" }}">
<td
class="ons-summary__item-title"
{% if rowItem.rowTitleAttributes is defined and rowItem.rowTitleAttributes %}{% for attribute, value in (rowItem.rowTitleAttributes.items() if rowItem.rowTitleAttributes is mapping and rowItem.rowTitleAttributes.items else rowItem.rowTitleAttributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.iconType is defined and rowItem.iconType %}
{% from "components/icons/_macro.njk" import onsIcon %}
<span class="ons-summary__item-title-icon {% if rowItem.iconType == 'check' %} ons-summary__item-title-icon--check{% endif %}">
{{
onsIcon({
"iconType": rowItem.iconType
})
}}
</span>
{% endif %}
<div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }} {{ hasIcons }}</div>
{# Render section status for mobile if is hub #}
{% if params.hub is defined and params.hub and rowItem.valueList is defined and rowItem.valueList %}
<span class="ons-u-d-no@s ons-u-fs-r"> — {{ rowItem.valueList[0].text | safe }}</span>
{% endif %}
</td>
{% if rowItem.valueList is defined and rowItem.valueList %}
<td
class="ons-summary__values"
{% if rowItem.actions == null %} colspan="2"{% endif %}
{% if rowItem.attributes is defined and rowItem.attributes %}{% for attribute, value in (rowItem.attributes.items() if rowItem.attributes is mapping and rowItem.attributes.items else rowItem.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.valueList | length == 1 %}
{{ rowItem.valueList[0].text | safe }}
{% if rowItem.valueList[0].other is defined and rowItem.valueList[0].other or rowItem.valueList[0].other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ rowItem.valueList[0].other | safe }}</li>
</ul>
{% endif %}
{% else %}
<ul class="ons-u-mb-no">
{% for value in (rowItem.valueList if rowItem.valueList is iterable else rowItem.valueList.items()) %}
<li>
{{ value.text | safe }}
{% if value.other is defined and value.other or value.other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ value.other | safe }}</li>
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endif %}
{% if rowItem.actions is defined and rowItem.actions %}
<td class="ons-summary__actions">
{% for action in (rowItem.actions if rowItem.actions is iterable else rowItem.actions.items()) %}
{% if loop.index > 1 %}<span class="ons-summary__spacer"></span>{% endif %}
<a
href="{{ action.url }}"
class="ons-summary__button"
{% if action.ariaLabel is defined and action.ariaLabel %} aria-label="{{ action.ariaLabel }}"{% endif %}
{% if action.attributes is defined and action.attributes %}{% for attribute, value in (action.attributes.items() if action.attributes is mapping and action.attributes.items else action.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>{{ action.text }}</a>
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% elif group.placeholderText is defined and group.placeholderText %}
{{ group.placeholderText }}
{% endif %}
{% if group.summaryLink is defined and group.summaryLink %}
<div class="{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %}ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
<a {% if group.summaryLink.attributes is defined and group.summaryLink.attributes %}{% for attribute, value in (group.summaryLink.attributes.items() if group.summaryLink.attributes is mapping and group.summaryLink.attributes.items else group.summaryLink.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %} href="{{ group.summaryLink.url }}">{{ group.summaryLink.text }}</a>
</div>
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endmacro %}
@use 'sass:math';
$summary-row-spacing: 1rem;
$summary-col-spacing: 1rem;
$hub-row-spacing: 1.3rem;
.ons-summary {
&__items {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
+ .ons-summary__group-title {
margin-top: 1.5rem;
}
}
&__item {
line-height: 1.4;
&:not(:last-child),
&:nth-of-type(1) {
border-bottom: 1px solid $color-borders;
}
&--total {
@extend .ons-u-fs-m;
border-width: 2px;
font-weight: 700;
}
&--error {
background: $color-errors-tint;
border-left: 8px solid $color-errors;
}
}
&__row-title {
padding: $summary-row-spacing 0;
text-align: left;
}
&__item-title,
&__values,
&__actions {
hyphens: manual;
overflow-wrap: break-word;
padding: 0 0 $summary-row-spacing;
vertical-align: top;
word-wrap: break-word;
}
&__item-title {
padding-top: $summary-row-spacing;
position: relative;
&--text {
display: block;
overflow: hidden;
padding-left: 2rem;
}
&-icon {
left: 0;
position: absolute;
text-align: center;
&--check .ons-svg-icon {
fill: $color-leaf-green !important;
}
}
}
&__actions {
white-space: nowrap;
}
&__spacer {
background: $color-black;
display: inline-block;
height: 1rem;
margin: 0 0.25rem;
vertical-align: middle;
width: 1px;
}
// Item Modifiers
&__item--total & {
&__values {
@extend .ons-u-fs-m;
}
}
&__item--error & {
&__row-title {
color: $color-errors;
font-weight: 700;
padding: $summary-row-spacing $summary-col-spacing;
}
&__item-title,
&__values,
&__actions {
padding-left: $summary-col-spacing;
padding-right: $summary-col-spacing;
@include mq('s') {
padding-left: math.div($summary-col-spacing, 2);
padding-right: math.div($summary-col-spacing, 2);
&:first-child {
padding-left: $summary-col-spacing;
}
&:last-child {
padding-right: $summary-col-spacing;
}
}
}
}
// Modifiers
&--hub & {
&__actions {
padding: 0 0 $hub-row-spacing;
}
&__item-title {
@extend .ons-u-fs-r--b;
padding-top: $hub-row-spacing;
}
}
&:not(&--hub) & {
&__values {
@extend .ons-u-fs-r--b;
}
}
// Breakpoints
@include mq(xxs, s, none, '<') {
&__item-title,
&__values,
&__actions {
display: block;
}
&--hub & {
&__values {
display: none;
}
}
}
@include mq(s) {
&__item-title,
&__values,
&__actions {
padding-top: $summary-row-spacing;
vertical-align: top;
&:not(:last-child) {
padding-right: $summary-col-spacing;
}
}
&__actions {
text-align: right;
}
&__row--has-values & {
&__item-title,
&__values {
width: 50%;
}
}
&--hub & {
&__item-title,
&__values,
&__actions {
padding-top: $hub-row-spacing;
}
}
}
}
Multiple
A summary of multiple answers to a single question.
<div class="ons-summary">
<h2 class="ons-summary__title ons-u-mb-m">Summary - Section Title</h2>
<div class="ons-summary__group">
<h3 class="ons-summary__group-title">What are your monthly household expenses?</h3>
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
<th>Question</th>
<th>Answer given</th>
<th>Change answer</th>
</tr>
</thead>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Food </div>
</td>
<td class="ons-summary__values">
£50.00
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Utilities </div>
</td>
<td class="ons-summary__values">
£65.00
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Transport </div>
</td>
<td class="ons-summary__values">
£70.00
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Other </div>
</td>
<td class="ons-summary__values">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
{% from "components/summary/_macro.njk" import onsSummary %}
{{
onsSummary({
"summaries": [
{
"summaryTitle": "Summary - Section Title",
"groups": [
{
"groupTitle": "What are your monthly household expenses?",
"headers":["Question", "Answer given", "Change answer"],
"rows": [
{
"rowItems": [
{
"rowTitle": "Food",
"valueList": [
{
"text": "£50.00"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
},
{
"rowTitle": "Utilities",
"valueList": [
{
"text": "£65.00"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
},
{
"rowTitle": "Transport",
"valueList": [
{
"text": "£70.00"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
},
{
"rowTitle": "Other",
"valueList": [
{
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
}
]
}
]
}
]
})
}}
{% macro onsSummary(params) %}
{% set className = "ons-summary" %}
{% set titleSize = "2" %}
{% if params.classes is defined and params.classes %}
{% set className = className + " " + params.classes %}
{% endif %}
{% if params.hub is defined and params.hub %}
{% set className = className + " ons-summary--hub" %}
{% endif %}
<div class="{{ className }}">
{% for summary in params.summaries %}
{% if summary.summaryTitle is defined and summary.summaryTitle %}
<h2 class="ons-summary__title ons-u-mb-m">{{ summary.summaryTitle }}</h2>
{% set titleSize = "3" %}
{% endif %}
{% for group in summary.groups %}
<div {% if group.id is defined and group.id %}id="{{ group.id }}" {% endif %} class="ons-summary__group">
{% if group.groupTitle is defined and group.groupTitle %}
<h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
{% endif %}
{% if group.headers is defined and group.headers and group.rows is defined and group.rows %}
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
{% for header in group.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
{% for row in (group.rows if group.rows is iterable else group.rows.items()) %}
{% set itemClass = "" %}
{% if row.error is defined and row.error %} {% set itemClass = " ons-summary__item--error" %}{% endif %}
{% if row.total is defined and row.total %} {% set itemClass = itemClass + " ons-summary__item--total" %}{% endif %}
<tbody {% if row.id is defined and row.id %}id="{{ row.id }}" {% endif %}class="ons-summary__item{{ itemClass }}">
{% if row.errorMessage is defined and row.errorMessage or (row.rowItems | length > 1 and row.rowTitle) %}
<tr class="ons-summary__row">
<th colspan="3" class="ons-summary__row-title ons-u-fs-r">{{ row.errorMessage or row.rowTitle }}</th>
</tr>
{% endif %}
{% for rowItem in row.rowItems %}
<tr {% if rowItem.id is defined and rowItem.id %}id="{{ rowItem.id }}" {% endif %}class="ons-summary__row{{ " ons-summary__row--has-values" if rowItem.valueList else "" }}">
<td
class="ons-summary__item-title"
{% if rowItem.rowTitleAttributes is defined and rowItem.rowTitleAttributes %}{% for attribute, value in (rowItem.rowTitleAttributes.items() if rowItem.rowTitleAttributes is mapping and rowItem.rowTitleAttributes.items else rowItem.rowTitleAttributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.iconType is defined and rowItem.iconType %}
{% from "components/icons/_macro.njk" import onsIcon %}
<span class="ons-summary__item-title-icon {% if rowItem.iconType == 'check' %} ons-summary__item-title-icon--check{% endif %}">
{{
onsIcon({
"iconType": rowItem.iconType
})
}}
</span>
{% endif %}
<div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }} {{ hasIcons }}</div>
{# Render section status for mobile if is hub #}
{% if params.hub is defined and params.hub and rowItem.valueList is defined and rowItem.valueList %}
<span class="ons-u-d-no@s ons-u-fs-r"> — {{ rowItem.valueList[0].text | safe }}</span>
{% endif %}
</td>
{% if rowItem.valueList is defined and rowItem.valueList %}
<td
class="ons-summary__values"
{% if rowItem.actions == null %} colspan="2"{% endif %}
{% if rowItem.attributes is defined and rowItem.attributes %}{% for attribute, value in (rowItem.attributes.items() if rowItem.attributes is mapping and rowItem.attributes.items else rowItem.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.valueList | length == 1 %}
{{ rowItem.valueList[0].text | safe }}
{% if rowItem.valueList[0].other is defined and rowItem.valueList[0].other or rowItem.valueList[0].other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ rowItem.valueList[0].other | safe }}</li>
</ul>
{% endif %}
{% else %}
<ul class="ons-u-mb-no">
{% for value in (rowItem.valueList if rowItem.valueList is iterable else rowItem.valueList.items()) %}
<li>
{{ value.text | safe }}
{% if value.other is defined and value.other or value.other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ value.other | safe }}</li>
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endif %}
{% if rowItem.actions is defined and rowItem.actions %}
<td class="ons-summary__actions">
{% for action in (rowItem.actions if rowItem.actions is iterable else rowItem.actions.items()) %}
{% if loop.index > 1 %}<span class="ons-summary__spacer"></span>{% endif %}
<a
href="{{ action.url }}"
class="ons-summary__button"
{% if action.ariaLabel is defined and action.ariaLabel %} aria-label="{{ action.ariaLabel }}"{% endif %}
{% if action.attributes is defined and action.attributes %}{% for attribute, value in (action.attributes.items() if action.attributes is mapping and action.attributes.items else action.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>{{ action.text }}</a>
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% elif group.placeholderText is defined and group.placeholderText %}
{{ group.placeholderText }}
{% endif %}
{% if group.summaryLink is defined and group.summaryLink %}
<div class="{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %}ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
<a {% if group.summaryLink.attributes is defined and group.summaryLink.attributes %}{% for attribute, value in (group.summaryLink.attributes.items() if group.summaryLink.attributes is mapping and group.summaryLink.attributes.items else group.summaryLink.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %} href="{{ group.summaryLink.url }}">{{ group.summaryLink.text }}</a>
</div>
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endmacro %}
@use 'sass:math';
$summary-row-spacing: 1rem;
$summary-col-spacing: 1rem;
$hub-row-spacing: 1.3rem;
.ons-summary {
&__items {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
+ .ons-summary__group-title {
margin-top: 1.5rem;
}
}
&__item {
line-height: 1.4;
&:not(:last-child),
&:nth-of-type(1) {
border-bottom: 1px solid $color-borders;
}
&--total {
@extend .ons-u-fs-m;
border-width: 2px;
font-weight: 700;
}
&--error {
background: $color-errors-tint;
border-left: 8px solid $color-errors;
}
}
&__row-title {
padding: $summary-row-spacing 0;
text-align: left;
}
&__item-title,
&__values,
&__actions {
hyphens: manual;
overflow-wrap: break-word;
padding: 0 0 $summary-row-spacing;
vertical-align: top;
word-wrap: break-word;
}
&__item-title {
padding-top: $summary-row-spacing;
position: relative;
&--text {
display: block;
overflow: hidden;
padding-left: 2rem;
}
&-icon {
left: 0;
position: absolute;
text-align: center;
&--check .ons-svg-icon {
fill: $color-leaf-green !important;
}
}
}
&__actions {
white-space: nowrap;
}
&__spacer {
background: $color-black;
display: inline-block;
height: 1rem;
margin: 0 0.25rem;
vertical-align: middle;
width: 1px;
}
// Item Modifiers
&__item--total & {
&__values {
@extend .ons-u-fs-m;
}
}
&__item--error & {
&__row-title {
color: $color-errors;
font-weight: 700;
padding: $summary-row-spacing $summary-col-spacing;
}
&__item-title,
&__values,
&__actions {
padding-left: $summary-col-spacing;
padding-right: $summary-col-spacing;
@include mq('s') {
padding-left: math.div($summary-col-spacing, 2);
padding-right: math.div($summary-col-spacing, 2);
&:first-child {
padding-left: $summary-col-spacing;
}
&:last-child {
padding-right: $summary-col-spacing;
}
}
}
}
// Modifiers
&--hub & {
&__actions {
padding: 0 0 $hub-row-spacing;
}
&__item-title {
@extend .ons-u-fs-r--b;
padding-top: $hub-row-spacing;
}
}
&:not(&--hub) & {
&__values {
@extend .ons-u-fs-r--b;
}
}
// Breakpoints
@include mq(xxs, s, none, '<') {
&__item-title,
&__values,
&__actions {
display: block;
}
&--hub & {
&__values {
display: none;
}
}
}
@include mq(s) {
&__item-title,
&__values,
&__actions {
padding-top: $summary-row-spacing;
vertical-align: top;
&:not(:last-child) {
padding-right: $summary-col-spacing;
}
}
&__actions {
text-align: right;
}
&__row--has-values & {
&__item-title,
&__values {
width: 50%;
}
}
&--hub & {
&__item-title,
&__values,
&__actions {
padding-top: $hub-row-spacing;
}
}
}
}
Total
<div class="ons-summary">
<div class="ons-summary__group">
<h2 class="ons-summary__group-title">Summary - Section Title</h2>
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
<th>Question</th>
<th>Answer given</th>
<th>Change answer</th>
</tr>
</thead>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Total value of acquisitions for transport assets and equipment </div>
</td>
<td class="ons-summary__values">
£9,000.00
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Total value of acquisitions for computers and peripheral devices (hardware) </div>
</td>
<td class="ons-summary__values">
£225,000.00
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item ons-summary__item--total">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Grand total for value of acquisitions </div>
</td>
<td class="ons-summary__values" colspan="2">
£234,000.00
</td>
</tr>
</tbody>
</table>
</div>
</div>
{% from "components/summary/_macro.njk" import onsSummary %}
{{
onsSummary({
"summaries": [
{
"groups": [
{
"groupTitle": "Summary - Section Title",
"headers":["Question", "Answer given", "Change answer"],
"rows": [
{
"rowTitle": "Total value of acquisitions for transport assets and equipment",
"rowItems": [
{
"valueList": [
{
"text": "£9,000.00"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "Total value of acquisitions for computers and peripheral devices (hardware)",
"rowItems": [
{
"valueList": [
{
"text": "£225,000.00"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "Grand total for value of acquisitions",
"total": true,
"rowItems": [
{
"valueList": [
{
"text": "£234,000.00"
}
]
}
]
}
]
}
]
}
]
})
}}
{% macro onsSummary(params) %}
{% set className = "ons-summary" %}
{% set titleSize = "2" %}
{% if params.classes is defined and params.classes %}
{% set className = className + " " + params.classes %}
{% endif %}
{% if params.hub is defined and params.hub %}
{% set className = className + " ons-summary--hub" %}
{% endif %}
<div class="{{ className }}">
{% for summary in params.summaries %}
{% if summary.summaryTitle is defined and summary.summaryTitle %}
<h2 class="ons-summary__title ons-u-mb-m">{{ summary.summaryTitle }}</h2>
{% set titleSize = "3" %}
{% endif %}
{% for group in summary.groups %}
<div {% if group.id is defined and group.id %}id="{{ group.id }}" {% endif %} class="ons-summary__group">
{% if group.groupTitle is defined and group.groupTitle %}
<h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
{% endif %}
{% if group.headers is defined and group.headers and group.rows is defined and group.rows %}
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
{% for header in group.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
{% for row in (group.rows if group.rows is iterable else group.rows.items()) %}
{% set itemClass = "" %}
{% if row.error is defined and row.error %} {% set itemClass = " ons-summary__item--error" %}{% endif %}
{% if row.total is defined and row.total %} {% set itemClass = itemClass + " ons-summary__item--total" %}{% endif %}
<tbody {% if row.id is defined and row.id %}id="{{ row.id }}" {% endif %}class="ons-summary__item{{ itemClass }}">
{% if row.errorMessage is defined and row.errorMessage or (row.rowItems | length > 1 and row.rowTitle) %}
<tr class="ons-summary__row">
<th colspan="3" class="ons-summary__row-title ons-u-fs-r">{{ row.errorMessage or row.rowTitle }}</th>
</tr>
{% endif %}
{% for rowItem in row.rowItems %}
<tr {% if rowItem.id is defined and rowItem.id %}id="{{ rowItem.id }}" {% endif %}class="ons-summary__row{{ " ons-summary__row--has-values" if rowItem.valueList else "" }}">
<td
class="ons-summary__item-title"
{% if rowItem.rowTitleAttributes is defined and rowItem.rowTitleAttributes %}{% for attribute, value in (rowItem.rowTitleAttributes.items() if rowItem.rowTitleAttributes is mapping and rowItem.rowTitleAttributes.items else rowItem.rowTitleAttributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.iconType is defined and rowItem.iconType %}
{% from "components/icons/_macro.njk" import onsIcon %}
<span class="ons-summary__item-title-icon {% if rowItem.iconType == 'check' %} ons-summary__item-title-icon--check{% endif %}">
{{
onsIcon({
"iconType": rowItem.iconType
})
}}
</span>
{% endif %}
<div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }} {{ hasIcons }}</div>
{# Render section status for mobile if is hub #}
{% if params.hub is defined and params.hub and rowItem.valueList is defined and rowItem.valueList %}
<span class="ons-u-d-no@s ons-u-fs-r"> — {{ rowItem.valueList[0].text | safe }}</span>
{% endif %}
</td>
{% if rowItem.valueList is defined and rowItem.valueList %}
<td
class="ons-summary__values"
{% if rowItem.actions == null %} colspan="2"{% endif %}
{% if rowItem.attributes is defined and rowItem.attributes %}{% for attribute, value in (rowItem.attributes.items() if rowItem.attributes is mapping and rowItem.attributes.items else rowItem.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.valueList | length == 1 %}
{{ rowItem.valueList[0].text | safe }}
{% if rowItem.valueList[0].other is defined and rowItem.valueList[0].other or rowItem.valueList[0].other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ rowItem.valueList[0].other | safe }}</li>
</ul>
{% endif %}
{% else %}
<ul class="ons-u-mb-no">
{% for value in (rowItem.valueList if rowItem.valueList is iterable else rowItem.valueList.items()) %}
<li>
{{ value.text | safe }}
{% if value.other is defined and value.other or value.other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ value.other | safe }}</li>
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endif %}
{% if rowItem.actions is defined and rowItem.actions %}
<td class="ons-summary__actions">
{% for action in (rowItem.actions if rowItem.actions is iterable else rowItem.actions.items()) %}
{% if loop.index > 1 %}<span class="ons-summary__spacer"></span>{% endif %}
<a
href="{{ action.url }}"
class="ons-summary__button"
{% if action.ariaLabel is defined and action.ariaLabel %} aria-label="{{ action.ariaLabel }}"{% endif %}
{% if action.attributes is defined and action.attributes %}{% for attribute, value in (action.attributes.items() if action.attributes is mapping and action.attributes.items else action.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>{{ action.text }}</a>
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% elif group.placeholderText is defined and group.placeholderText %}
{{ group.placeholderText }}
{% endif %}
{% if group.summaryLink is defined and group.summaryLink %}
<div class="{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %}ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
<a {% if group.summaryLink.attributes is defined and group.summaryLink.attributes %}{% for attribute, value in (group.summaryLink.attributes.items() if group.summaryLink.attributes is mapping and group.summaryLink.attributes.items else group.summaryLink.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %} href="{{ group.summaryLink.url }}">{{ group.summaryLink.text }}</a>
</div>
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endmacro %}
@use 'sass:math';
$summary-row-spacing: 1rem;
$summary-col-spacing: 1rem;
$hub-row-spacing: 1.3rem;
.ons-summary {
&__items {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
+ .ons-summary__group-title {
margin-top: 1.5rem;
}
}
&__item {
line-height: 1.4;
&:not(:last-child),
&:nth-of-type(1) {
border-bottom: 1px solid $color-borders;
}
&--total {
@extend .ons-u-fs-m;
border-width: 2px;
font-weight: 700;
}
&--error {
background: $color-errors-tint;
border-left: 8px solid $color-errors;
}
}
&__row-title {
padding: $summary-row-spacing 0;
text-align: left;
}
&__item-title,
&__values,
&__actions {
hyphens: manual;
overflow-wrap: break-word;
padding: 0 0 $summary-row-spacing;
vertical-align: top;
word-wrap: break-word;
}
&__item-title {
padding-top: $summary-row-spacing;
position: relative;
&--text {
display: block;
overflow: hidden;
padding-left: 2rem;
}
&-icon {
left: 0;
position: absolute;
text-align: center;
&--check .ons-svg-icon {
fill: $color-leaf-green !important;
}
}
}
&__actions {
white-space: nowrap;
}
&__spacer {
background: $color-black;
display: inline-block;
height: 1rem;
margin: 0 0.25rem;
vertical-align: middle;
width: 1px;
}
// Item Modifiers
&__item--total & {
&__values {
@extend .ons-u-fs-m;
}
}
&__item--error & {
&__row-title {
color: $color-errors;
font-weight: 700;
padding: $summary-row-spacing $summary-col-spacing;
}
&__item-title,
&__values,
&__actions {
padding-left: $summary-col-spacing;
padding-right: $summary-col-spacing;
@include mq('s') {
padding-left: math.div($summary-col-spacing, 2);
padding-right: math.div($summary-col-spacing, 2);
&:first-child {
padding-left: $summary-col-spacing;
}
&:last-child {
padding-right: $summary-col-spacing;
}
}
}
}
// Modifiers
&--hub & {
&__actions {
padding: 0 0 $hub-row-spacing;
}
&__item-title {
@extend .ons-u-fs-r--b;
padding-top: $hub-row-spacing;
}
}
&:not(&--hub) & {
&__values {
@extend .ons-u-fs-r--b;
}
}
// Breakpoints
@include mq(xxs, s, none, '<') {
&__item-title,
&__values,
&__actions {
display: block;
}
&--hub & {
&__values {
display: none;
}
}
}
@include mq(s) {
&__item-title,
&__values,
&__actions {
padding-top: $summary-row-spacing;
vertical-align: top;
&:not(:last-child) {
padding-right: $summary-col-spacing;
}
}
&__actions {
text-align: right;
}
&__row--has-values & {
&__item-title,
&__values {
width: 50%;
}
}
&--hub & {
&__item-title,
&__values,
&__actions {
padding-top: $hub-row-spacing;
}
}
}
}
Household
<div class="ons-summary ons-u-mb-l">
<div class="ons-summary__group">
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody class="ons-summary__item">
<tr class="ons-summary__row">
<td class="ons-summary__item-title">
<span class="ons-summary__item-title-icon ">
<svg class="ons-svg-icon" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg" focusable="false" fill="currentColor">
<path d="M7,9H9a5,5,0,0,1,5,5H2A5,5,0,0,1,7,9Z" transform="translate(-2 -2)" />
<circle cx="6" cy="3" r="3" />
</svg>
</span>
<div class="ons-summary__item--text ons-summary__item-title--text">Joe Bloggs (You) </div>
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change details for Joe Bloggs">Change</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row">
<td class="ons-summary__item-title">
<span class="ons-summary__item-title-icon ">
<svg class="ons-svg-icon" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg" focusable="false" fill="currentColor">
<path d="M7,9H9a5,5,0,0,1,5,5H2A5,5,0,0,1,7,9Z" transform="translate(-2 -2)" />
<circle cx="6" cy="3" r="3" />
</svg>
</span>
<div class="ons-summary__item--text ons-summary__item-title--text">Barry Scott </div>
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change details for Barry Scott">Change</a>
<span class="ons-summary__spacer"></span>
<a href="#0" class="ons-summary__button" aria-label="Remove Barry Scott">Remove</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row">
<td class="ons-summary__item-title">
<span class="ons-summary__item-title-icon ">
<svg class="ons-svg-icon" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg" focusable="false" fill="currentColor">
<path d="M7,9H9a5,5,0,0,1,5,5H2A5,5,0,0,1,7,9Z" transform="translate(-2 -2)" />
<circle cx="6" cy="3" r="3" />
</svg>
</span>
<div class="ons-summary__item--text ons-summary__item-title--text">Wilhelmina Susannah Clementine-Smith </div>
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change details for Susan Gill">Change</a>
<span class="ons-summary__spacer"></span>
<a href="#0" class="ons-summary__button" aria-label="Remove Susan Gill">Remove</a>
</td>
</tr>
</tbody>
</table>
<div class="ons-u-pt-s ons-u-bt">
<a data-qa="add-item-link" href="#0">Add someone to this household</a>
</div>
</div>
</div>
{% from "components/summary/_macro.njk" import onsSummary %}
{{ onsSummary({
"classes": "ons-u-mb-l",
"summaries": [
{
"groups": [
{
"headers":["Name", "Action"],
"rows": [
{
"rowTitle": "Joe Bloggs (You)",
"rowItems": [
{
"iconType": "person",
"actions": [
{
"text": "Change",
"ariaLabel": "Change details for Joe Bloggs",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "Barry Scott",
"rowItems": [
{
"iconType": "person",
"actions": [
{
"text": "Change",
"ariaLabel": "Change details for Barry Scott",
"url": "#0"
},
{
"text": "Remove",
"ariaLabel": "Remove Barry Scott",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "Wilhelmina Susannah Clementine-Smith",
"rowItems": [
{
"iconType": "person",
"actions": [
{
"text": "Change",
"ariaLabel": "Change details for Susan Gill",
"url": "#0"
},
{
"text": "Remove",
"ariaLabel": "Remove Susan Gill",
"url": "#0"
}
]
}
]
}
],
"summaryLink": {
"text": "Add someone to this household",
"url": "#0",
"attributes": {
"data-qa": "add-item-link"
}
}
}
]
}
]
}) }}
{% macro onsSummary(params) %}
{% set className = "ons-summary" %}
{% set titleSize = "2" %}
{% if params.classes is defined and params.classes %}
{% set className = className + " " + params.classes %}
{% endif %}
{% if params.hub is defined and params.hub %}
{% set className = className + " ons-summary--hub" %}
{% endif %}
<div class="{{ className }}">
{% for summary in params.summaries %}
{% if summary.summaryTitle is defined and summary.summaryTitle %}
<h2 class="ons-summary__title ons-u-mb-m">{{ summary.summaryTitle }}</h2>
{% set titleSize = "3" %}
{% endif %}
{% for group in summary.groups %}
<div {% if group.id is defined and group.id %}id="{{ group.id }}" {% endif %} class="ons-summary__group">
{% if group.groupTitle is defined and group.groupTitle %}
<h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
{% endif %}
{% if group.headers is defined and group.headers and group.rows is defined and group.rows %}
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
{% for header in group.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
{% for row in (group.rows if group.rows is iterable else group.rows.items()) %}
{% set itemClass = "" %}
{% if row.error is defined and row.error %} {% set itemClass = " ons-summary__item--error" %}{% endif %}
{% if row.total is defined and row.total %} {% set itemClass = itemClass + " ons-summary__item--total" %}{% endif %}
<tbody {% if row.id is defined and row.id %}id="{{ row.id }}" {% endif %}class="ons-summary__item{{ itemClass }}">
{% if row.errorMessage is defined and row.errorMessage or (row.rowItems | length > 1 and row.rowTitle) %}
<tr class="ons-summary__row">
<th colspan="3" class="ons-summary__row-title ons-u-fs-r">{{ row.errorMessage or row.rowTitle }}</th>
</tr>
{% endif %}
{% for rowItem in row.rowItems %}
<tr {% if rowItem.id is defined and rowItem.id %}id="{{ rowItem.id }}" {% endif %}class="ons-summary__row{{ " ons-summary__row--has-values" if rowItem.valueList else "" }}">
<td
class="ons-summary__item-title"
{% if rowItem.rowTitleAttributes is defined and rowItem.rowTitleAttributes %}{% for attribute, value in (rowItem.rowTitleAttributes.items() if rowItem.rowTitleAttributes is mapping and rowItem.rowTitleAttributes.items else rowItem.rowTitleAttributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.iconType is defined and rowItem.iconType %}
{% from "components/icons/_macro.njk" import onsIcon %}
<span class="ons-summary__item-title-icon {% if rowItem.iconType == 'check' %} ons-summary__item-title-icon--check{% endif %}">
{{
onsIcon({
"iconType": rowItem.iconType
})
}}
</span>
{% endif %}
<div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }} {{ hasIcons }}</div>
{# Render section status for mobile if is hub #}
{% if params.hub is defined and params.hub and rowItem.valueList is defined and rowItem.valueList %}
<span class="ons-u-d-no@s ons-u-fs-r"> — {{ rowItem.valueList[0].text | safe }}</span>
{% endif %}
</td>
{% if rowItem.valueList is defined and rowItem.valueList %}
<td
class="ons-summary__values"
{% if rowItem.actions == null %} colspan="2"{% endif %}
{% if rowItem.attributes is defined and rowItem.attributes %}{% for attribute, value in (rowItem.attributes.items() if rowItem.attributes is mapping and rowItem.attributes.items else rowItem.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.valueList | length == 1 %}
{{ rowItem.valueList[0].text | safe }}
{% if rowItem.valueList[0].other is defined and rowItem.valueList[0].other or rowItem.valueList[0].other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ rowItem.valueList[0].other | safe }}</li>
</ul>
{% endif %}
{% else %}
<ul class="ons-u-mb-no">
{% for value in (rowItem.valueList if rowItem.valueList is iterable else rowItem.valueList.items()) %}
<li>
{{ value.text | safe }}
{% if value.other is defined and value.other or value.other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ value.other | safe }}</li>
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endif %}
{% if rowItem.actions is defined and rowItem.actions %}
<td class="ons-summary__actions">
{% for action in (rowItem.actions if rowItem.actions is iterable else rowItem.actions.items()) %}
{% if loop.index > 1 %}<span class="ons-summary__spacer"></span>{% endif %}
<a
href="{{ action.url }}"
class="ons-summary__button"
{% if action.ariaLabel is defined and action.ariaLabel %} aria-label="{{ action.ariaLabel }}"{% endif %}
{% if action.attributes is defined and action.attributes %}{% for attribute, value in (action.attributes.items() if action.attributes is mapping and action.attributes.items else action.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>{{ action.text }}</a>
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% elif group.placeholderText is defined and group.placeholderText %}
{{ group.placeholderText }}
{% endif %}
{% if group.summaryLink is defined and group.summaryLink %}
<div class="{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %}ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
<a {% if group.summaryLink.attributes is defined and group.summaryLink.attributes %}{% for attribute, value in (group.summaryLink.attributes.items() if group.summaryLink.attributes is mapping and group.summaryLink.attributes.items else group.summaryLink.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %} href="{{ group.summaryLink.url }}">{{ group.summaryLink.text }}</a>
</div>
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endmacro %}
@use 'sass:math';
$summary-row-spacing: 1rem;
$summary-col-spacing: 1rem;
$hub-row-spacing: 1.3rem;
.ons-summary {
&__items {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
+ .ons-summary__group-title {
margin-top: 1.5rem;
}
}
&__item {
line-height: 1.4;
&:not(:last-child),
&:nth-of-type(1) {
border-bottom: 1px solid $color-borders;
}
&--total {
@extend .ons-u-fs-m;
border-width: 2px;
font-weight: 700;
}
&--error {
background: $color-errors-tint;
border-left: 8px solid $color-errors;
}
}
&__row-title {
padding: $summary-row-spacing 0;
text-align: left;
}
&__item-title,
&__values,
&__actions {
hyphens: manual;
overflow-wrap: break-word;
padding: 0 0 $summary-row-spacing;
vertical-align: top;
word-wrap: break-word;
}
&__item-title {
padding-top: $summary-row-spacing;
position: relative;
&--text {
display: block;
overflow: hidden;
padding-left: 2rem;
}
&-icon {
left: 0;
position: absolute;
text-align: center;
&--check .ons-svg-icon {
fill: $color-leaf-green !important;
}
}
}
&__actions {
white-space: nowrap;
}
&__spacer {
background: $color-black;
display: inline-block;
height: 1rem;
margin: 0 0.25rem;
vertical-align: middle;
width: 1px;
}
// Item Modifiers
&__item--total & {
&__values {
@extend .ons-u-fs-m;
}
}
&__item--error & {
&__row-title {
color: $color-errors;
font-weight: 700;
padding: $summary-row-spacing $summary-col-spacing;
}
&__item-title,
&__values,
&__actions {
padding-left: $summary-col-spacing;
padding-right: $summary-col-spacing;
@include mq('s') {
padding-left: math.div($summary-col-spacing, 2);
padding-right: math.div($summary-col-spacing, 2);
&:first-child {
padding-left: $summary-col-spacing;
}
&:last-child {
padding-right: $summary-col-spacing;
}
}
}
}
// Modifiers
&--hub & {
&__actions {
padding: 0 0 $hub-row-spacing;
}
&__item-title {
@extend .ons-u-fs-r--b;
padding-top: $hub-row-spacing;
}
}
&:not(&--hub) & {
&__values {
@extend .ons-u-fs-r--b;
}
}
// Breakpoints
@include mq(xxs, s, none, '<') {
&__item-title,
&__values,
&__actions {
display: block;
}
&--hub & {
&__values {
display: none;
}
}
}
@include mq(s) {
&__item-title,
&__values,
&__actions {
padding-top: $summary-row-spacing;
vertical-align: top;
&:not(:last-child) {
padding-right: $summary-col-spacing;
}
}
&__actions {
text-align: right;
}
&__row--has-values & {
&__item-title,
&__values {
width: 50%;
}
}
&--hub & {
&__item-title,
&__values,
&__actions {
padding-top: $hub-row-spacing;
}
}
}
}
Household no rows
If there are no rows returned the summary will render placeholder text
<div class="ons-summary">
<div class="ons-summary__group">
There are no householders
<div class="ons-u-pt-s">
<a data-qa="add-item-link" href="#0">Add someone to this household</a>
</div>
</div>
</div>
{% from "components/summary/_macro.njk" import onsSummary %}
{{ onsSummary({
"summaries": [
{
"groups": [
{
"headers":["Name", "Action"],
"placeholderText": "There are no householders",
"summaryLink": {
"text": "Add someone to this household",
"url": "#0",
"attributes": {
"data-qa": "add-item-link"
}
}
}
]
}
]
}) }}
{% macro onsSummary(params) %}
{% set className = "ons-summary" %}
{% set titleSize = "2" %}
{% if params.classes is defined and params.classes %}
{% set className = className + " " + params.classes %}
{% endif %}
{% if params.hub is defined and params.hub %}
{% set className = className + " ons-summary--hub" %}
{% endif %}
<div class="{{ className }}">
{% for summary in params.summaries %}
{% if summary.summaryTitle is defined and summary.summaryTitle %}
<h2 class="ons-summary__title ons-u-mb-m">{{ summary.summaryTitle }}</h2>
{% set titleSize = "3" %}
{% endif %}
{% for group in summary.groups %}
<div {% if group.id is defined and group.id %}id="{{ group.id }}" {% endif %} class="ons-summary__group">
{% if group.groupTitle is defined and group.groupTitle %}
<h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
{% endif %}
{% if group.headers is defined and group.headers and group.rows is defined and group.rows %}
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
{% for header in group.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
{% for row in (group.rows if group.rows is iterable else group.rows.items()) %}
{% set itemClass = "" %}
{% if row.error is defined and row.error %} {% set itemClass = " ons-summary__item--error" %}{% endif %}
{% if row.total is defined and row.total %} {% set itemClass = itemClass + " ons-summary__item--total" %}{% endif %}
<tbody {% if row.id is defined and row.id %}id="{{ row.id }}" {% endif %}class="ons-summary__item{{ itemClass }}">
{% if row.errorMessage is defined and row.errorMessage or (row.rowItems | length > 1 and row.rowTitle) %}
<tr class="ons-summary__row">
<th colspan="3" class="ons-summary__row-title ons-u-fs-r">{{ row.errorMessage or row.rowTitle }}</th>
</tr>
{% endif %}
{% for rowItem in row.rowItems %}
<tr {% if rowItem.id is defined and rowItem.id %}id="{{ rowItem.id }}" {% endif %}class="ons-summary__row{{ " ons-summary__row--has-values" if rowItem.valueList else "" }}">
<td
class="ons-summary__item-title"
{% if rowItem.rowTitleAttributes is defined and rowItem.rowTitleAttributes %}{% for attribute, value in (rowItem.rowTitleAttributes.items() if rowItem.rowTitleAttributes is mapping and rowItem.rowTitleAttributes.items else rowItem.rowTitleAttributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.iconType is defined and rowItem.iconType %}
{% from "components/icons/_macro.njk" import onsIcon %}
<span class="ons-summary__item-title-icon {% if rowItem.iconType == 'check' %} ons-summary__item-title-icon--check{% endif %}">
{{
onsIcon({
"iconType": rowItem.iconType
})
}}
</span>
{% endif %}
<div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }} {{ hasIcons }}</div>
{# Render section status for mobile if is hub #}
{% if params.hub is defined and params.hub and rowItem.valueList is defined and rowItem.valueList %}
<span class="ons-u-d-no@s ons-u-fs-r"> — {{ rowItem.valueList[0].text | safe }}</span>
{% endif %}
</td>
{% if rowItem.valueList is defined and rowItem.valueList %}
<td
class="ons-summary__values"
{% if rowItem.actions == null %} colspan="2"{% endif %}
{% if rowItem.attributes is defined and rowItem.attributes %}{% for attribute, value in (rowItem.attributes.items() if rowItem.attributes is mapping and rowItem.attributes.items else rowItem.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.valueList | length == 1 %}
{{ rowItem.valueList[0].text | safe }}
{% if rowItem.valueList[0].other is defined and rowItem.valueList[0].other or rowItem.valueList[0].other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ rowItem.valueList[0].other | safe }}</li>
</ul>
{% endif %}
{% else %}
<ul class="ons-u-mb-no">
{% for value in (rowItem.valueList if rowItem.valueList is iterable else rowItem.valueList.items()) %}
<li>
{{ value.text | safe }}
{% if value.other is defined and value.other or value.other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ value.other | safe }}</li>
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endif %}
{% if rowItem.actions is defined and rowItem.actions %}
<td class="ons-summary__actions">
{% for action in (rowItem.actions if rowItem.actions is iterable else rowItem.actions.items()) %}
{% if loop.index > 1 %}<span class="ons-summary__spacer"></span>{% endif %}
<a
href="{{ action.url }}"
class="ons-summary__button"
{% if action.ariaLabel is defined and action.ariaLabel %} aria-label="{{ action.ariaLabel }}"{% endif %}
{% if action.attributes is defined and action.attributes %}{% for attribute, value in (action.attributes.items() if action.attributes is mapping and action.attributes.items else action.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>{{ action.text }}</a>
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% elif group.placeholderText is defined and group.placeholderText %}
{{ group.placeholderText }}
{% endif %}
{% if group.summaryLink is defined and group.summaryLink %}
<div class="{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %}ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
<a {% if group.summaryLink.attributes is defined and group.summaryLink.attributes %}{% for attribute, value in (group.summaryLink.attributes.items() if group.summaryLink.attributes is mapping and group.summaryLink.attributes.items else group.summaryLink.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %} href="{{ group.summaryLink.url }}">{{ group.summaryLink.text }}</a>
</div>
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endmacro %}
@use 'sass:math';
$summary-row-spacing: 1rem;
$summary-col-spacing: 1rem;
$hub-row-spacing: 1.3rem;
.ons-summary {
&__items {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
+ .ons-summary__group-title {
margin-top: 1.5rem;
}
}
&__item {
line-height: 1.4;
&:not(:last-child),
&:nth-of-type(1) {
border-bottom: 1px solid $color-borders;
}
&--total {
@extend .ons-u-fs-m;
border-width: 2px;
font-weight: 700;
}
&--error {
background: $color-errors-tint;
border-left: 8px solid $color-errors;
}
}
&__row-title {
padding: $summary-row-spacing 0;
text-align: left;
}
&__item-title,
&__values,
&__actions {
hyphens: manual;
overflow-wrap: break-word;
padding: 0 0 $summary-row-spacing;
vertical-align: top;
word-wrap: break-word;
}
&__item-title {
padding-top: $summary-row-spacing;
position: relative;
&--text {
display: block;
overflow: hidden;
padding-left: 2rem;
}
&-icon {
left: 0;
position: absolute;
text-align: center;
&--check .ons-svg-icon {
fill: $color-leaf-green !important;
}
}
}
&__actions {
white-space: nowrap;
}
&__spacer {
background: $color-black;
display: inline-block;
height: 1rem;
margin: 0 0.25rem;
vertical-align: middle;
width: 1px;
}
// Item Modifiers
&__item--total & {
&__values {
@extend .ons-u-fs-m;
}
}
&__item--error & {
&__row-title {
color: $color-errors;
font-weight: 700;
padding: $summary-row-spacing $summary-col-spacing;
}
&__item-title,
&__values,
&__actions {
padding-left: $summary-col-spacing;
padding-right: $summary-col-spacing;
@include mq('s') {
padding-left: math.div($summary-col-spacing, 2);
padding-right: math.div($summary-col-spacing, 2);
&:first-child {
padding-left: $summary-col-spacing;
}
&:last-child {
padding-right: $summary-col-spacing;
}
}
}
}
// Modifiers
&--hub & {
&__actions {
padding: 0 0 $hub-row-spacing;
}
&__item-title {
@extend .ons-u-fs-r--b;
padding-top: $hub-row-spacing;
}
}
&:not(&--hub) & {
&__values {
@extend .ons-u-fs-r--b;
}
}
// Breakpoints
@include mq(xxs, s, none, '<') {
&__item-title,
&__values,
&__actions {
display: block;
}
&--hub & {
&__values {
display: none;
}
}
}
@include mq(s) {
&__item-title,
&__values,
&__actions {
padding-top: $summary-row-spacing;
vertical-align: top;
&:not(:last-child) {
padding-right: $summary-col-spacing;
}
}
&__actions {
text-align: right;
}
&__row--has-values & {
&__item-title,
&__values {
width: 50%;
}
}
&--hub & {
&__item-title,
&__values,
&__actions {
padding-top: $hub-row-spacing;
}
}
}
}
Hub
<div class="ons-summary ons-summary--hub">
<div class="ons-summary__group">
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
<th>Name of section or person</th>
<th>Section progress</th>
<th>Access section</th>
</tr>
</thead>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<span class="ons-summary__item-title-icon ons-summary__item-title-icon--check">
<svg class="ons-svg-icon" viewBox="0 0 13 10" xmlns="http://www.w3.org/2000/svg" focusable="false" fill="currentColor">
<path d="M14.35,3.9l-.71-.71a.5.5,0,0,0-.71,0h0L5.79,10.34,3.07,7.61a.51.51,0,0,0-.71,0l-.71.71a.51.51,0,0,0,0,.71l3.78,3.78a.5.5,0,0,0,.71,0h0L14.35,4.6A.5.5,0,0,0,14.35,3.9Z" transform="translate(-1.51 -3.04)" />
</svg>
</span>
<div class="ons-summary__item--text ons-summary__item-title--text">People who live here </div>
<span class="ons-u-d-no@s ons-u-fs-r"> — Completed</span>
</td>
<td class="ons-summary__values">
Completed
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="View answers for People who live here">View answers</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<span class="ons-summary__item-title-icon ons-summary__item-title-icon--check">
<svg class="ons-svg-icon" viewBox="0 0 13 10" xmlns="http://www.w3.org/2000/svg" focusable="false" fill="currentColor">
<path d="M14.35,3.9l-.71-.71a.5.5,0,0,0-.71,0h0L5.79,10.34,3.07,7.61a.51.51,0,0,0-.71,0l-.71.71a.51.51,0,0,0,0,.71l3.78,3.78a.5.5,0,0,0,.71,0h0L14.35,4.6A.5.5,0,0,0,14.35,3.9Z" transform="translate(-1.51 -3.04)" />
</svg>
</span>
<div class="ons-summary__item--text ons-summary__item-title--text">Accommodation </div>
<span class="ons-u-d-no@s ons-u-fs-r"> — Completed</span>
</td>
<td class="ons-summary__values">
Completed
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="View answers for Accommodation">View answers</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<span class="ons-summary__item-title-icon ons-summary__item-title-icon--check">
<svg class="ons-svg-icon" viewBox="0 0 13 10" xmlns="http://www.w3.org/2000/svg" focusable="false" fill="currentColor">
<path d="M14.35,3.9l-.71-.71a.5.5,0,0,0-.71,0h0L5.79,10.34,3.07,7.61a.51.51,0,0,0-.71,0l-.71.71a.51.51,0,0,0,0,.71l3.78,3.78a.5.5,0,0,0,.71,0h0L14.35,4.6A.5.5,0,0,0,14.35,3.9Z" transform="translate(-1.51 -3.04)" />
</svg>
</span>
<div class="ons-summary__item--text ons-summary__item-title--text">Mary Smith (You) </div>
<span class="ons-u-d-no@s ons-u-fs-r"> — Completed</span>
</td>
<td class="ons-summary__values">
Completed
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="View answers for Mary Smith">View answers</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">John Smith </div>
<span class="ons-u-d-no@s ons-u-fs-r"> — Partially completed</span>
</td>
<td class="ons-summary__values">
Partially completed
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Continue with John Smith's section">Continue with section</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Billy Smith </div>
<span class="ons-u-d-no@s ons-u-fs-r"> — Not started</span>
</td>
<td class="ons-summary__values">
Not started
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Start Billy Smith's section">Start section</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Sally Smith </div>
<span class="ons-u-d-no@s ons-u-fs-r"> — Not started</span>
</td>
<td class="ons-summary__values">
Not started
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Start Sally Smith's section">Start section</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Wilhelmina Susannah Clementine-Smith (Visitor) </div>
<span class="ons-u-d-no@s ons-u-fs-r"> — Not started</span>
</td>
<td class="ons-summary__values">
Not started
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Start Wilhelmina Susannah Clementine-Smith's section">Start section</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">Vera Jones (Visitor) </div>
<span class="ons-u-d-no@s ons-u-fs-r"> — Not started</span>
</td>
<td class="ons-summary__values">
Not started
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Start Vera Jones's section">Start section</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
{% from "components/summary/_macro.njk" import onsSummary %}
{{ onsSummary({
"hub": true,
"summaries": [
{
"groups": [
{
"headers":["Name of section or person", "Section progress", "Access section"],
"rows": [
{
"rowTitle": "People who live here",
"rowItems": [
{
"iconType": "check",
"valueList": [
{
"text": "Completed"
}
],
"actions": [
{
"text": "View answers",
"ariaLabel": "View answers for People who live here",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "Accommodation",
"rowItems": [
{
"iconType": "check",
"valueList": [
{
"text": "Completed"
}
],
"actions": [
{
"text": "View answers",
"ariaLabel": "View answers for Accommodation",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "Mary Smith (You)",
"rowItems": [
{
"iconType": "check",
"valueList": [
{
"text": "Completed"
}
],
"actions": [
{
"text": "View answers",
"ariaLabel": "View answers for Mary Smith",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "John Smith",
"rowItems": [
{
"valueList": [
{
"text": "Partially completed"
}
],
"actions": [
{
"text": "Continue with section",
"ariaLabel": "Continue with John Smith's section",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "Billy Smith",
"rowItems": [
{
"valueList": [
{
"text": "Not started"
}
],
"actions": [
{
"text": "Start section",
"ariaLabel": "Start Billy Smith's section",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "Sally Smith",
"rowItems": [
{
"valueList": [
{
"text": "Not started"
}
],
"actions": [
{
"text": "Start section",
"ariaLabel": "Start Sally Smith's section",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "Wilhelmina Susannah Clementine-Smith (Visitor)",
"rowItems": [
{
"valueList": [
{
"text": "Not started"
}
],
"actions": [
{
"text": "Start section",
"ariaLabel": "Start Wilhelmina Susannah Clementine-Smith's section",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "Vera Jones (Visitor)",
"rowItems": [
{
"valueList": [
{
"text": "Not started"
}
],
"actions": [
{
"text": "Start section",
"ariaLabel": "Start Vera Jones's section",
"url": "#0"
}
]
}
]
}
]
}
]
}
]
}) }}
{% macro onsSummary(params) %}
{% set className = "ons-summary" %}
{% set titleSize = "2" %}
{% if params.classes is defined and params.classes %}
{% set className = className + " " + params.classes %}
{% endif %}
{% if params.hub is defined and params.hub %}
{% set className = className + " ons-summary--hub" %}
{% endif %}
<div class="{{ className }}">
{% for summary in params.summaries %}
{% if summary.summaryTitle is defined and summary.summaryTitle %}
<h2 class="ons-summary__title ons-u-mb-m">{{ summary.summaryTitle }}</h2>
{% set titleSize = "3" %}
{% endif %}
{% for group in summary.groups %}
<div {% if group.id is defined and group.id %}id="{{ group.id }}" {% endif %} class="ons-summary__group">
{% if group.groupTitle is defined and group.groupTitle %}
<h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
{% endif %}
{% if group.headers is defined and group.headers and group.rows is defined and group.rows %}
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
{% for header in group.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
{% for row in (group.rows if group.rows is iterable else group.rows.items()) %}
{% set itemClass = "" %}
{% if row.error is defined and row.error %} {% set itemClass = " ons-summary__item--error" %}{% endif %}
{% if row.total is defined and row.total %} {% set itemClass = itemClass + " ons-summary__item--total" %}{% endif %}
<tbody {% if row.id is defined and row.id %}id="{{ row.id }}" {% endif %}class="ons-summary__item{{ itemClass }}">
{% if row.errorMessage is defined and row.errorMessage or (row.rowItems | length > 1 and row.rowTitle) %}
<tr class="ons-summary__row">
<th colspan="3" class="ons-summary__row-title ons-u-fs-r">{{ row.errorMessage or row.rowTitle }}</th>
</tr>
{% endif %}
{% for rowItem in row.rowItems %}
<tr {% if rowItem.id is defined and rowItem.id %}id="{{ rowItem.id }}" {% endif %}class="ons-summary__row{{ " ons-summary__row--has-values" if rowItem.valueList else "" }}">
<td
class="ons-summary__item-title"
{% if rowItem.rowTitleAttributes is defined and rowItem.rowTitleAttributes %}{% for attribute, value in (rowItem.rowTitleAttributes.items() if rowItem.rowTitleAttributes is mapping and rowItem.rowTitleAttributes.items else rowItem.rowTitleAttributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.iconType is defined and rowItem.iconType %}
{% from "components/icons/_macro.njk" import onsIcon %}
<span class="ons-summary__item-title-icon {% if rowItem.iconType == 'check' %} ons-summary__item-title-icon--check{% endif %}">
{{
onsIcon({
"iconType": rowItem.iconType
})
}}
</span>
{% endif %}
<div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }} {{ hasIcons }}</div>
{# Render section status for mobile if is hub #}
{% if params.hub is defined and params.hub and rowItem.valueList is defined and rowItem.valueList %}
<span class="ons-u-d-no@s ons-u-fs-r"> — {{ rowItem.valueList[0].text | safe }}</span>
{% endif %}
</td>
{% if rowItem.valueList is defined and rowItem.valueList %}
<td
class="ons-summary__values"
{% if rowItem.actions == null %} colspan="2"{% endif %}
{% if rowItem.attributes is defined and rowItem.attributes %}{% for attribute, value in (rowItem.attributes.items() if rowItem.attributes is mapping and rowItem.attributes.items else rowItem.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.valueList | length == 1 %}
{{ rowItem.valueList[0].text | safe }}
{% if rowItem.valueList[0].other is defined and rowItem.valueList[0].other or rowItem.valueList[0].other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ rowItem.valueList[0].other | safe }}</li>
</ul>
{% endif %}
{% else %}
<ul class="ons-u-mb-no">
{% for value in (rowItem.valueList if rowItem.valueList is iterable else rowItem.valueList.items()) %}
<li>
{{ value.text | safe }}
{% if value.other is defined and value.other or value.other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ value.other | safe }}</li>
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endif %}
{% if rowItem.actions is defined and rowItem.actions %}
<td class="ons-summary__actions">
{% for action in (rowItem.actions if rowItem.actions is iterable else rowItem.actions.items()) %}
{% if loop.index > 1 %}<span class="ons-summary__spacer"></span>{% endif %}
<a
href="{{ action.url }}"
class="ons-summary__button"
{% if action.ariaLabel is defined and action.ariaLabel %} aria-label="{{ action.ariaLabel }}"{% endif %}
{% if action.attributes is defined and action.attributes %}{% for attribute, value in (action.attributes.items() if action.attributes is mapping and action.attributes.items else action.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>{{ action.text }}</a>
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% elif group.placeholderText is defined and group.placeholderText %}
{{ group.placeholderText }}
{% endif %}
{% if group.summaryLink is defined and group.summaryLink %}
<div class="{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %}ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
<a {% if group.summaryLink.attributes is defined and group.summaryLink.attributes %}{% for attribute, value in (group.summaryLink.attributes.items() if group.summaryLink.attributes is mapping and group.summaryLink.attributes.items else group.summaryLink.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %} href="{{ group.summaryLink.url }}">{{ group.summaryLink.text }}</a>
</div>
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endmacro %}
@use 'sass:math';
$summary-row-spacing: 1rem;
$summary-col-spacing: 1rem;
$hub-row-spacing: 1.3rem;
.ons-summary {
&__items {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
+ .ons-summary__group-title {
margin-top: 1.5rem;
}
}
&__item {
line-height: 1.4;
&:not(:last-child),
&:nth-of-type(1) {
border-bottom: 1px solid $color-borders;
}
&--total {
@extend .ons-u-fs-m;
border-width: 2px;
font-weight: 700;
}
&--error {
background: $color-errors-tint;
border-left: 8px solid $color-errors;
}
}
&__row-title {
padding: $summary-row-spacing 0;
text-align: left;
}
&__item-title,
&__values,
&__actions {
hyphens: manual;
overflow-wrap: break-word;
padding: 0 0 $summary-row-spacing;
vertical-align: top;
word-wrap: break-word;
}
&__item-title {
padding-top: $summary-row-spacing;
position: relative;
&--text {
display: block;
overflow: hidden;
padding-left: 2rem;
}
&-icon {
left: 0;
position: absolute;
text-align: center;
&--check .ons-svg-icon {
fill: $color-leaf-green !important;
}
}
}
&__actions {
white-space: nowrap;
}
&__spacer {
background: $color-black;
display: inline-block;
height: 1rem;
margin: 0 0.25rem;
vertical-align: middle;
width: 1px;
}
// Item Modifiers
&__item--total & {
&__values {
@extend .ons-u-fs-m;
}
}
&__item--error & {
&__row-title {
color: $color-errors;
font-weight: 700;
padding: $summary-row-spacing $summary-col-spacing;
}
&__item-title,
&__values,
&__actions {
padding-left: $summary-col-spacing;
padding-right: $summary-col-spacing;
@include mq('s') {
padding-left: math.div($summary-col-spacing, 2);
padding-right: math.div($summary-col-spacing, 2);
&:first-child {
padding-left: $summary-col-spacing;
}
&:last-child {
padding-right: $summary-col-spacing;
}
}
}
}
// Modifiers
&--hub & {
&__actions {
padding: 0 0 $hub-row-spacing;
}
&__item-title {
@extend .ons-u-fs-r--b;
padding-top: $hub-row-spacing;
}
}
&:not(&--hub) & {
&__values {
@extend .ons-u-fs-r--b;
}
}
// Breakpoints
@include mq(xxs, s, none, '<') {
&__item-title,
&__values,
&__actions {
display: block;
}
&--hub & {
&__values {
display: none;
}
}
}
@include mq(s) {
&__item-title,
&__values,
&__actions {
padding-top: $summary-row-spacing;
vertical-align: top;
&:not(:last-child) {
padding-right: $summary-col-spacing;
}
}
&__actions {
text-align: right;
}
&__row--has-values & {
&__item-title,
&__values {
width: 50%;
}
}
&--hub & {
&__item-title,
&__values,
&__actions {
padding-top: $hub-row-spacing;
}
}
}
}
How to check a summary of figures
To help users validate a summary of their previous numerical answers, you should:
- check that their answers entered on previous pages are accurate
- show an error message if they are not accurate, for example, figures given for percentages do not sum to 100%
Error messages
Use the correct errors pattern and show the error details above the group of rows in summary.
<div class="ons-summary">
<div class="ons-summary__group">
<h2 class="ons-summary__group-title">Summary - Section Title</h2>
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
<th>Question</th>
<th>Answer given</th>
<th>Change answer</th>
</tr>
</thead>
<tbody class="ons-summary__item">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">For the period 1 May 2017 to 31 May 2017, what was the total turnover of Essential Enterprise Ltd.? </div>
</td>
<td class="ons-summary__values">
£600.00
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item ons-summary__item--error">
<tr class="ons-summary__row">
<th colspan="3" class="ons-summary__row-title ons-u-fs-r">Change one or more of the figures so they sum to £600</th>
</tr>
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">What was the value of the business's total sales of food? </div>
</td>
<td class="ons-summary__values">
£123.00
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item ons-summary__item--error">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">What was the value of the business's total sales of alcohol, confectionery and tobacco? </div>
</td>
<td class="ons-summary__values">
£200.00
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
<tbody class="ons-summary__item ons-summary__item--error">
<tr class="ons-summary__row ons-summary__row--has-values">
<td class="ons-summary__item-title">
<div class="ons-summary__item--text">What was the value of the business's total sales of clothing and footwear? </div>
</td>
<td class="ons-summary__values">
£50.00
</td>
<td class="ons-summary__actions">
<a href="#0" class="ons-summary__button" aria-label="Change answer">Change</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
{% from "components/summary/_macro.njk" import onsSummary %}
{{
onsSummary({
"summaries": [
{
"groups": [
{
"groupTitle": "Summary - Section Title",
"headers":["Question", "Answer given", "Change answer"],
"rows": [
{
"rowTitle": "For the period 1 May 2017 to 31 May 2017, what was the total turnover of Essential Enterprise Ltd.?",
"rowItems": [
{
"valueList": [
{
"text": "£600.00"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "What was the value of the business's total sales of food?",
"errorMessage": "Change one or more of the figures so they sum to £600",
"error": true,
"rowItems": [
{
"valueList": [
{
"text": "£123.00"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "What was the value of the business's total sales of alcohol, confectionery and tobacco?",
"error": true,
"rowItems": [
{
"valueList": [
{
"text": "£200.00"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
},
{
"rowTitle": "What was the value of the business's total sales of clothing and footwear?",
"error": true,
"rowItems": [
{
"valueList": [
{
"text": "£50.00"
}
],
"actions": [
{
"text": "Change",
"ariaLabel": "Change answer",
"url": "#0"
}
]
}
]
}
]
}
]
}
]
})
}}
{% macro onsSummary(params) %}
{% set className = "ons-summary" %}
{% set titleSize = "2" %}
{% if params.classes is defined and params.classes %}
{% set className = className + " " + params.classes %}
{% endif %}
{% if params.hub is defined and params.hub %}
{% set className = className + " ons-summary--hub" %}
{% endif %}
<div class="{{ className }}">
{% for summary in params.summaries %}
{% if summary.summaryTitle is defined and summary.summaryTitle %}
<h2 class="ons-summary__title ons-u-mb-m">{{ summary.summaryTitle }}</h2>
{% set titleSize = "3" %}
{% endif %}
{% for group in summary.groups %}
<div {% if group.id is defined and group.id %}id="{{ group.id }}" {% endif %} class="ons-summary__group">
{% if group.groupTitle is defined and group.groupTitle %}
<h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
{% endif %}
{% if group.headers is defined and group.headers and group.rows is defined and group.rows %}
<table class="ons-summary__items">
<thead class="ons-u-vh">
<tr>
{% for header in group.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
{% for row in (group.rows if group.rows is iterable else group.rows.items()) %}
{% set itemClass = "" %}
{% if row.error is defined and row.error %} {% set itemClass = " ons-summary__item--error" %}{% endif %}
{% if row.total is defined and row.total %} {% set itemClass = itemClass + " ons-summary__item--total" %}{% endif %}
<tbody {% if row.id is defined and row.id %}id="{{ row.id }}" {% endif %}class="ons-summary__item{{ itemClass }}">
{% if row.errorMessage is defined and row.errorMessage or (row.rowItems | length > 1 and row.rowTitle) %}
<tr class="ons-summary__row">
<th colspan="3" class="ons-summary__row-title ons-u-fs-r">{{ row.errorMessage or row.rowTitle }}</th>
</tr>
{% endif %}
{% for rowItem in row.rowItems %}
<tr {% if rowItem.id is defined and rowItem.id %}id="{{ rowItem.id }}" {% endif %}class="ons-summary__row{{ " ons-summary__row--has-values" if rowItem.valueList else "" }}">
<td
class="ons-summary__item-title"
{% if rowItem.rowTitleAttributes is defined and rowItem.rowTitleAttributes %}{% for attribute, value in (rowItem.rowTitleAttributes.items() if rowItem.rowTitleAttributes is mapping and rowItem.rowTitleAttributes.items else rowItem.rowTitleAttributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.iconType is defined and rowItem.iconType %}
{% from "components/icons/_macro.njk" import onsIcon %}
<span class="ons-summary__item-title-icon {% if rowItem.iconType == 'check' %} ons-summary__item-title-icon--check{% endif %}">
{{
onsIcon({
"iconType": rowItem.iconType
})
}}
</span>
{% endif %}
<div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }} {{ hasIcons }}</div>
{# Render section status for mobile if is hub #}
{% if params.hub is defined and params.hub and rowItem.valueList is defined and rowItem.valueList %}
<span class="ons-u-d-no@s ons-u-fs-r"> — {{ rowItem.valueList[0].text | safe }}</span>
{% endif %}
</td>
{% if rowItem.valueList is defined and rowItem.valueList %}
<td
class="ons-summary__values"
{% if rowItem.actions == null %} colspan="2"{% endif %}
{% if rowItem.attributes is defined and rowItem.attributes %}{% for attribute, value in (rowItem.attributes.items() if rowItem.attributes is mapping and rowItem.attributes.items else rowItem.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>
{% if rowItem.valueList | length == 1 %}
{{ rowItem.valueList[0].text | safe }}
{% if rowItem.valueList[0].other is defined and rowItem.valueList[0].other or rowItem.valueList[0].other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ rowItem.valueList[0].other | safe }}</li>
</ul>
{% endif %}
{% else %}
<ul class="ons-u-mb-no">
{% for value in (rowItem.valueList if rowItem.valueList is iterable else rowItem.valueList.items()) %}
<li>
{{ value.text | safe }}
{% if value.other is defined and value.other or value.other == 0 %}
<ul class="ons-u-mb-no">
<li>{{ value.other | safe }}</li>
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endif %}
{% if rowItem.actions is defined and rowItem.actions %}
<td class="ons-summary__actions">
{% for action in (rowItem.actions if rowItem.actions is iterable else rowItem.actions.items()) %}
{% if loop.index > 1 %}<span class="ons-summary__spacer"></span>{% endif %}
<a
href="{{ action.url }}"
class="ons-summary__button"
{% if action.ariaLabel is defined and action.ariaLabel %} aria-label="{{ action.ariaLabel }}"{% endif %}
{% if action.attributes is defined and action.attributes %}{% for attribute, value in (action.attributes.items() if action.attributes is mapping and action.attributes.items else action.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
>{{ action.text }}</a>
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% elif group.placeholderText is defined and group.placeholderText %}
{{ group.placeholderText }}
{% endif %}
{% if group.summaryLink is defined and group.summaryLink %}
<div class="{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %}ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
<a {% if group.summaryLink.attributes is defined and group.summaryLink.attributes %}{% for attribute, value in (group.summaryLink.attributes.items() if group.summaryLink.attributes is mapping and group.summaryLink.attributes.items else group.summaryLink.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %} href="{{ group.summaryLink.url }}">{{ group.summaryLink.text }}</a>
</div>
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
{% endmacro %}
@use 'sass:math';
$summary-row-spacing: 1rem;
$summary-col-spacing: 1rem;
$hub-row-spacing: 1.3rem;
.ons-summary {
&__items {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
+ .ons-summary__group-title {
margin-top: 1.5rem;
}
}
&__item {
line-height: 1.4;
&:not(:last-child),
&:nth-of-type(1) {
border-bottom: 1px solid $color-borders;
}
&--total {
@extend .ons-u-fs-m;
border-width: 2px;
font-weight: 700;
}
&--error {
background: $color-errors-tint;
border-left: 8px solid $color-errors;
}
}
&__row-title {
padding: $summary-row-spacing 0;
text-align: left;
}
&__item-title,
&__values,
&__actions {
hyphens: manual;
overflow-wrap: break-word;
padding: 0 0 $summary-row-spacing;
vertical-align: top;
word-wrap: break-word;
}
&__item-title {
padding-top: $summary-row-spacing;
position: relative;
&--text {
display: block;
overflow: hidden;
padding-left: 2rem;
}
&-icon {
left: 0;
position: absolute;
text-align: center;
&--check .ons-svg-icon {
fill: $color-leaf-green !important;
}
}
}
&__actions {
white-space: nowrap;
}
&__spacer {
background: $color-black;
display: inline-block;
height: 1rem;
margin: 0 0.25rem;
vertical-align: middle;
width: 1px;
}
// Item Modifiers
&__item--total & {
&__values {
@extend .ons-u-fs-m;
}
}
&__item--error & {
&__row-title {
color: $color-errors;
font-weight: 700;
padding: $summary-row-spacing $summary-col-spacing;
}
&__item-title,
&__values,
&__actions {
padding-left: $summary-col-spacing;
padding-right: $summary-col-spacing;
@include mq('s') {
padding-left: math.div($summary-col-spacing, 2);
padding-right: math.div($summary-col-spacing, 2);
&:first-child {
padding-left: $summary-col-spacing;
}
&:last-child {
padding-right: $summary-col-spacing;
}
}
}
}
// Modifiers
&--hub & {
&__actions {
padding: 0 0 $hub-row-spacing;
}
&__item-title {
@extend .ons-u-fs-r--b;
padding-top: $hub-row-spacing;
}
}
&:not(&--hub) & {
&__values {
@extend .ons-u-fs-r--b;
}
}
// Breakpoints
@include mq(xxs, s, none, '<') {
&__item-title,
&__values,
&__actions {
display: block;
}
&--hub & {
&__values {
display: none;
}
}
}
@include mq(s) {
&__item-title,
&__values,
&__actions {
padding-top: $summary-row-spacing;
vertical-align: top;
&:not(:last-child) {
padding-right: $summary-col-spacing;
}
}
&__actions {
text-align: right;
}
&__row--has-values & {
&__item-title,
&__values {
width: 50%;
}
}
&--hub & {
&__item-title,
&__values,
&__actions {
padding-top: $hub-row-spacing;
}
}
}
}
If there are any errors in the summary
Use “Change one or more of the figures so they sum to [the required amount]”.
For example, “Change one or more of the figures so they sum to £600”.
Help improve this component
Let us know how we could improve this component or share your user research findings. Discuss the ‘Summary’ component on GitHub