Skip to main content

Summary

A summary presents a clear summarised output of values to the user.

<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>
          <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">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 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 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 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">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 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">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": [
                    {
                    "groupTitle": "Turnover",
                    "headers":["Question", "Answer given", "Change answer"],
                    "rows": [
                        {
                            "rowTitle": "What are the dates of the sales period you are reporting for?",
                            "rowItems": [
                                {
                                    "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?",
                            "rowItems": [
                                {
                                    "valueList": [
                                        {
                                            "text": "£180,440"
                                        }
                                    ],
                                    "actions": [
                                        {
                                            "text": "Change",
                                            "ariaLabel": "Change answer",
                                            "url": "#0"
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "rowTitle": "Please indicate the reasons for any changes in the total turnover",
                            "rowItems": [
                                {
                                    "valueList": [
                                        {
                                            "text": "Change in level of business activity"
                                        },
                                        {
                                            "text": "Special/calendar events",
                                            "other": "Some other value"
                                        }
                                    ],
                                    "actions": [
                                        {
                                            "text": "Change",
                                            "ariaLabel": "Change answer",
                                            "url": "#0"
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "rowTitle": "Please describe the changes in total turnover in more detail",
                            "rowItems": [
                                {
                                    "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"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
  })
}}
Name Type Required Description
summaries Array<Summaries> true An array of summaries
classes string false Classes to add to the summary component
hub boolean false Whether to render the summary in as a hub

Summaries

Name Type Required Description
groups Array<SummaryGroup> true An array of groups within a summary
summaryTitle string false The title for a group of summaries

SummaryGroup

Name Type Required Description
rows Array<SummaryRows> false An array of rows within a group
placeholderText string false A message to be shown as a placeholder if there are no rows in the summary
groupTitle string false The title for a summary within a group
headers Array<SummaryHeaders> false An array of headers to describe the data in the summary
summaryLink Array<SummaryLink> false Settings for the link to appear after the summary

SummaryRow

Name Type Required Description
rowItems Array<SummaryRowItem> true An array of items for this row
rowtitle string false The title for the row
rowTitleAttributes object false HTML attributes (for example, data attributes) to add to the rowTitle
error boolean false Whether to render this item as an error
errorMessage string false Error message for the row
total boolean false Whether to render this item as a total

SummaryRowItem

Name Type Required Description
iconType string false Name of the icon to be placed next to the title
title string false Label for the row item
valueList Array<SummaryValue> false The value(s) to the row item
actions Array<SummaryAction> false Configurations for action links. If not specified no links will render
attributes object false HTML attributes (for example, data attributes) to add to the row item

SummaryValue

Name Type Required Description
text string true The display value
other string false The display value for the “other” input on a checkbox or radio

SummaryAction

Name Type Required Description
text string true Text for the action link
url string true URL to edit the answer
ariaLabel string false An aria-label to apply to the link if you need it to be more verbose for screen readers
attributes object false HTML attributes (for example, data attributes) to add to the action link
Name Type Required Description
url string true The url for the link to follow the summary
text string true The text for the link to follow the summary
attributes object false HTML attributes (for example, data attributes) to add to the summary 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 %}
            <div class="ons-summary__group">
                {% 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 %}
                    {% if group.groupTitle is defined and group.groupTitle %}
                        <h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
                    {% endif %}
                    {% if group.rows is defined and group.rows %}
                        <table class="ons-summary__items">
                            {% if group.headers is defined and group.headers %}
                                <thead class="ons-u-vh">
                                    <tr>
                                        {% for header in group.headers %}
                                            <th>{{ header }}</th>
                                        {% endfor %}
                                    </tr>
                                </thead>
                            {% endif %}

                            {% 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 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 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 %}
                {% endfor %}
            </div>
        {% endfor %}
    </div>
{% endmacro %}
$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: $summary-col-spacing / 2;
        padding-right: $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

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"
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    })
}}
Name Type Required Description
summaries Array<Summaries> true An array of summaries
classes string false Classes to add to the summary component
hub boolean false Whether to render the summary in as a hub

Summaries

Name Type Required Description
groups Array<SummaryGroup> true An array of groups within a summary
summaryTitle string false The title for a group of summaries

SummaryGroup

Name Type Required Description
rows Array<SummaryRows> false An array of rows within a group
placeholderText string false A message to be shown as a placeholder if there are no rows in the summary
groupTitle string false The title for a summary within a group
headers Array<SummaryHeaders> false An array of headers to describe the data in the summary
summaryLink Array<SummaryLink> false Settings for the link to appear after the summary

SummaryRow

Name Type Required Description
rowItems Array<SummaryRowItem> true An array of items for this row
rowtitle string false The title for the row
rowTitleAttributes object false HTML attributes (for example, data attributes) to add to the rowTitle
error boolean false Whether to render this item as an error
errorMessage string false Error message for the row
total boolean false Whether to render this item as a total

SummaryRowItem

Name Type Required Description
iconType string false Name of the icon to be placed next to the title
title string false Label for the row item
valueList Array<SummaryValue> false The value(s) to the row item
actions Array<SummaryAction> false Configurations for action links. If not specified no links will render
attributes object false HTML attributes (for example, data attributes) to add to the row item

SummaryValue

Name Type Required Description
text string true The display value
other string false The display value for the “other” input on a checkbox or radio

SummaryAction

Name Type Required Description
text string true Text for the action link
url string true URL to edit the answer
ariaLabel string false An aria-label to apply to the link if you need it to be more verbose for screen readers
attributes object false HTML attributes (for example, data attributes) to add to the action link
Name Type Required Description
url string true The url for the link to follow the summary
text string true The text for the link to follow the summary
attributes object false HTML attributes (for example, data attributes) to add to the summary 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 %}
            <div class="ons-summary__group">
                {% 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 %}
                    {% if group.groupTitle is defined and group.groupTitle %}
                        <h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
                    {% endif %}
                    {% if group.rows is defined and group.rows %}
                        <table class="ons-summary__items">
                            {% if group.headers is defined and group.headers %}
                                <thead class="ons-u-vh">
                                    <tr>
                                        {% for header in group.headers %}
                                            <th>{{ header }}</th>
                                        {% endfor %}
                                    </tr>
                                </thead>
                            {% endif %}

                            {% 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 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 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 %}
                {% endfor %}
            </div>
        {% endfor %}
    </div>
{% endmacro %}
$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: $summary-col-spacing / 2;
        padding-right: $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">
  <div class="ons-summary__group">
    <h2 class="ons-summary__title ons-u-mb-m">John Doe</h2>
    <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>
    <h3 class="ons-summary__group-title">Identity and health</h3>
    <table class="ons-summary__items">
      <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>
    <h3 class="ons-summary__group-title">Qualifications</h3>
    <table class="ons-summary__items">
      <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",
                        "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",
                        "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"
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    })
}}

Name Type Required Description
summaries Array<Summaries> true An array of summaries
classes string false Classes to add to the summary component
hub boolean false Whether to render the summary in as a hub

Summaries

Name Type Required Description
groups Array<SummaryGroup> true An array of groups within a summary
summaryTitle string false The title for a group of summaries

SummaryGroup

Name Type Required Description
rows Array<SummaryRows> false An array of rows within a group
placeholderText string false A message to be shown as a placeholder if there are no rows in the summary
groupTitle string false The title for a summary within a group
headers Array<SummaryHeaders> false An array of headers to describe the data in the summary
summaryLink Array<SummaryLink> false Settings for the link to appear after the summary

SummaryRow

Name Type Required Description
rowItems Array<SummaryRowItem> true An array of items for this row
rowtitle string false The title for the row
rowTitleAttributes object false HTML attributes (for example, data attributes) to add to the rowTitle
error boolean false Whether to render this item as an error
errorMessage string false Error message for the row
total boolean false Whether to render this item as a total

SummaryRowItem

Name Type Required Description
iconType string false Name of the icon to be placed next to the title
title string false Label for the row item
valueList Array<SummaryValue> false The value(s) to the row item
actions Array<SummaryAction> false Configurations for action links. If not specified no links will render
attributes object false HTML attributes (for example, data attributes) to add to the row item

SummaryValue

Name Type Required Description
text string true The display value
other string false The display value for the “other” input on a checkbox or radio

SummaryAction

Name Type Required Description
text string true Text for the action link
url string true URL to edit the answer
ariaLabel string false An aria-label to apply to the link if you need it to be more verbose for screen readers
attributes object false HTML attributes (for example, data attributes) to add to the action link
Name Type Required Description
url string true The url for the link to follow the summary
text string true The text for the link to follow the summary
attributes object false HTML attributes (for example, data attributes) to add to the summary 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 %}
            <div class="ons-summary__group">
                {% 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 %}
                    {% if group.groupTitle is defined and group.groupTitle %}
                        <h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
                    {% endif %}
                    {% if group.rows is defined and group.rows %}
                        <table class="ons-summary__items">
                            {% if group.headers is defined and group.headers %}
                                <thead class="ons-u-vh">
                                    <tr>
                                        {% for header in group.headers %}
                                            <th>{{ header }}</th>
                                        {% endfor %}
                                    </tr>
                                </thead>
                            {% endif %}

                            {% 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 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 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 %}
                {% endfor %}
            </div>
        {% endfor %}
    </div>
{% endmacro %}
$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: $summary-col-spacing / 2;
        padding-right: $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">
  <div class="ons-summary__group">
    <h2 class="ons-summary__title ons-u-mb-m">Summary - Section Title</h2>
    <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"
                                            }
                                    ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    })
}}
Name Type Required Description
summaries Array<Summaries> true An array of summaries
classes string false Classes to add to the summary component
hub boolean false Whether to render the summary in as a hub

Summaries

Name Type Required Description
groups Array<SummaryGroup> true An array of groups within a summary
summaryTitle string false The title for a group of summaries

SummaryGroup

Name Type Required Description
rows Array<SummaryRows> false An array of rows within a group
placeholderText string false A message to be shown as a placeholder if there are no rows in the summary
groupTitle string false The title for a summary within a group
headers Array<SummaryHeaders> false An array of headers to describe the data in the summary
summaryLink Array<SummaryLink> false Settings for the link to appear after the summary

SummaryRow

Name Type Required Description
rowItems Array<SummaryRowItem> true An array of items for this row
rowtitle string false The title for the row
rowTitleAttributes object false HTML attributes (for example, data attributes) to add to the rowTitle
error boolean false Whether to render this item as an error
errorMessage string false Error message for the row
total boolean false Whether to render this item as a total

SummaryRowItem

Name Type Required Description
iconType string false Name of the icon to be placed next to the title
title string false Label for the row item
valueList Array<SummaryValue> false The value(s) to the row item
actions Array<SummaryAction> false Configurations for action links. If not specified no links will render
attributes object false HTML attributes (for example, data attributes) to add to the row item

SummaryValue

Name Type Required Description
text string true The display value
other string false The display value for the “other” input on a checkbox or radio

SummaryAction

Name Type Required Description
text string true Text for the action link
url string true URL to edit the answer
ariaLabel string false An aria-label to apply to the link if you need it to be more verbose for screen readers
attributes object false HTML attributes (for example, data attributes) to add to the action link
Name Type Required Description
url string true The url for the link to follow the summary
text string true The text for the link to follow the summary
attributes object false HTML attributes (for example, data attributes) to add to the summary 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 %}
            <div class="ons-summary__group">
                {% 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 %}
                    {% if group.groupTitle is defined and group.groupTitle %}
                        <h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
                    {% endif %}
                    {% if group.rows is defined and group.rows %}
                        <table class="ons-summary__items">
                            {% if group.headers is defined and group.headers %}
                                <thead class="ons-u-vh">
                                    <tr>
                                        {% for header in group.headers %}
                                            <th>{{ header }}</th>
                                        {% endfor %}
                                    </tr>
                                </thead>
                            {% endif %}

                            {% 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 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 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 %}
                {% endfor %}
            </div>
        {% endfor %}
    </div>
{% endmacro %}
$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: $summary-col-spacing / 2;
        padding-right: $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"
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    })
}}
Name Type Required Description
summaries Array<Summaries> true An array of summaries
classes string false Classes to add to the summary component
hub boolean false Whether to render the summary in as a hub

Summaries

Name Type Required Description
groups Array<SummaryGroup> true An array of groups within a summary
summaryTitle string false The title for a group of summaries

SummaryGroup

Name Type Required Description
rows Array<SummaryRows> false An array of rows within a group
placeholderText string false A message to be shown as a placeholder if there are no rows in the summary
groupTitle string false The title for a summary within a group
headers Array<SummaryHeaders> false An array of headers to describe the data in the summary
summaryLink Array<SummaryLink> false Settings for the link to appear after the summary

SummaryRow

Name Type Required Description
rowItems Array<SummaryRowItem> true An array of items for this row
rowtitle string false The title for the row
rowTitleAttributes object false HTML attributes (for example, data attributes) to add to the rowTitle
error boolean false Whether to render this item as an error
errorMessage string false Error message for the row
total boolean false Whether to render this item as a total

SummaryRowItem

Name Type Required Description
iconType string false Name of the icon to be placed next to the title
title string false Label for the row item
valueList Array<SummaryValue> false The value(s) to the row item
actions Array<SummaryAction> false Configurations for action links. If not specified no links will render
attributes object false HTML attributes (for example, data attributes) to add to the row item

SummaryValue

Name Type Required Description
text string true The display value
other string false The display value for the “other” input on a checkbox or radio

SummaryAction

Name Type Required Description
text string true Text for the action link
url string true URL to edit the answer
ariaLabel string false An aria-label to apply to the link if you need it to be more verbose for screen readers
attributes object false HTML attributes (for example, data attributes) to add to the action link
Name Type Required Description
url string true The url for the link to follow the summary
text string true The text for the link to follow the summary
attributes object false HTML attributes (for example, data attributes) to add to the summary 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 %}
            <div class="ons-summary__group">
                {% 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 %}
                    {% if group.groupTitle is defined and group.groupTitle %}
                        <h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
                    {% endif %}
                    {% if group.rows is defined and group.rows %}
                        <table class="ons-summary__items">
                            {% if group.headers is defined and group.headers %}
                                <thead class="ons-u-vh">
                                    <tr>
                                        {% for header in group.headers %}
                                            <th>{{ header }}</th>
                                        {% endfor %}
                                    </tr>
                                </thead>
                            {% endif %}

                            {% 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 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 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 %}
                {% endfor %}
            </div>
        {% endfor %}
    </div>
{% endmacro %}
$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: $summary-col-spacing / 2;
        padding-right: $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"
                        }
                    }
                }
            ]
        }
    ]
}) }}
Name Type Required Description
summaries Array<Summaries> true An array of summaries
classes string false Classes to add to the summary component
hub boolean false Whether to render the summary in as a hub

Summaries

Name Type Required Description
groups Array<SummaryGroup> true An array of groups within a summary
summaryTitle string false The title for a group of summaries

SummaryGroup

Name Type Required Description
rows Array<SummaryRows> false An array of rows within a group
placeholderText string false A message to be shown as a placeholder if there are no rows in the summary
groupTitle string false The title for a summary within a group
headers Array<SummaryHeaders> false An array of headers to describe the data in the summary
summaryLink Array<SummaryLink> false Settings for the link to appear after the summary

SummaryRow

Name Type Required Description
rowItems Array<SummaryRowItem> true An array of items for this row
rowtitle string false The title for the row
rowTitleAttributes object false HTML attributes (for example, data attributes) to add to the rowTitle
error boolean false Whether to render this item as an error
errorMessage string false Error message for the row
total boolean false Whether to render this item as a total

SummaryRowItem

Name Type Required Description
iconType string false Name of the icon to be placed next to the title
title string false Label for the row item
valueList Array<SummaryValue> false The value(s) to the row item
actions Array<SummaryAction> false Configurations for action links. If not specified no links will render
attributes object false HTML attributes (for example, data attributes) to add to the row item

SummaryValue

Name Type Required Description
text string true The display value
other string false The display value for the “other” input on a checkbox or radio

SummaryAction

Name Type Required Description
text string true Text for the action link
url string true URL to edit the answer
ariaLabel string false An aria-label to apply to the link if you need it to be more verbose for screen readers
attributes object false HTML attributes (for example, data attributes) to add to the action link
Name Type Required Description
url string true The url for the link to follow the summary
text string true The text for the link to follow the summary
attributes object false HTML attributes (for example, data attributes) to add to the summary 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 %}
            <div class="ons-summary__group">
                {% 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 %}
                    {% if group.groupTitle is defined and group.groupTitle %}
                        <h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
                    {% endif %}
                    {% if group.rows is defined and group.rows %}
                        <table class="ons-summary__items">
                            {% if group.headers is defined and group.headers %}
                                <thead class="ons-u-vh">
                                    <tr>
                                        {% for header in group.headers %}
                                            <th>{{ header }}</th>
                                        {% endfor %}
                                    </tr>
                                </thead>
                            {% endif %}

                            {% 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 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 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 %}
                {% endfor %}
            </div>
        {% endfor %}
    </div>
{% endmacro %}
$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: $summary-col-spacing / 2;
        padding-right: $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"
                        }
                    }
                }
            ]
        }
    ]
}) }}
Name Type Required Description
summaries Array<Summaries> true An array of summaries
classes string false Classes to add to the summary component
hub boolean false Whether to render the summary in as a hub

Summaries

Name Type Required Description
groups Array<SummaryGroup> true An array of groups within a summary
summaryTitle string false The title for a group of summaries

SummaryGroup

Name Type Required Description
rows Array<SummaryRows> false An array of rows within a group
placeholderText string false A message to be shown as a placeholder if there are no rows in the summary
groupTitle string false The title for a summary within a group
headers Array<SummaryHeaders> false An array of headers to describe the data in the summary
summaryLink Array<SummaryLink> false Settings for the link to appear after the summary

SummaryRow

Name Type Required Description
rowItems Array<SummaryRowItem> true An array of items for this row
rowtitle string false The title for the row
rowTitleAttributes object false HTML attributes (for example, data attributes) to add to the rowTitle
error boolean false Whether to render this item as an error
errorMessage string false Error message for the row
total boolean false Whether to render this item as a total

SummaryRowItem

Name Type Required Description
iconType string false Name of the icon to be placed next to the title
title string false Label for the row item
valueList Array<SummaryValue> false The value(s) to the row item
actions Array<SummaryAction> false Configurations for action links. If not specified no links will render
attributes object false HTML attributes (for example, data attributes) to add to the row item

SummaryValue

Name Type Required Description
text string true The display value
other string false The display value for the “other” input on a checkbox or radio

SummaryAction

Name Type Required Description
text string true Text for the action link
url string true URL to edit the answer
ariaLabel string false An aria-label to apply to the link if you need it to be more verbose for screen readers
attributes object false HTML attributes (for example, data attributes) to add to the action link
Name Type Required Description
url string true The url for the link to follow the summary
text string true The text for the link to follow the summary
attributes object false HTML attributes (for example, data attributes) to add to the summary 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 %}
            <div class="ons-summary__group">
                {% 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 %}
                    {% if group.groupTitle is defined and group.groupTitle %}
                        <h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
                    {% endif %}
                    {% if group.rows is defined and group.rows %}
                        <table class="ons-summary__items">
                            {% if group.headers is defined and group.headers %}
                                <thead class="ons-u-vh">
                                    <tr>
                                        {% for header in group.headers %}
                                            <th>{{ header }}</th>
                                        {% endfor %}
                                    </tr>
                                </thead>
                            {% endif %}

                            {% 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 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 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 %}
                {% endfor %}
            </div>
        {% endfor %}
    </div>
{% endmacro %}
$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: $summary-col-spacing / 2;
        padding-right: $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">Accomodation </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 Accomodation">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&#39;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&#39;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&#39;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&#39;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&#39;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": "Accomodation",
                            "rowItems": [
                                {
                                    "iconType": "check",
                                    "valueList": [
                                        {
                                            "text": "Completed"
                                        }
                                    ],
                                    "actions": [
                                        {
                                            "text": "View answers",
                                            "ariaLabel": "View answers for Accomodation",
                                            "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"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}) }}
Name Type Required Description
summaries Array<Summaries> true An array of summaries
classes string false Classes to add to the summary component
hub boolean false Whether to render the summary in as a hub

Summaries

Name Type Required Description
groups Array<SummaryGroup> true An array of groups within a summary
summaryTitle string false The title for a group of summaries

SummaryGroup

Name Type Required Description
rows Array<SummaryRows> false An array of rows within a group
placeholderText string false A message to be shown as a placeholder if there are no rows in the summary
groupTitle string false The title for a summary within a group
headers Array<SummaryHeaders> false An array of headers to describe the data in the summary
summaryLink Array<SummaryLink> false Settings for the link to appear after the summary

SummaryRow

Name Type Required Description
rowItems Array<SummaryRowItem> true An array of items for this row
rowtitle string false The title for the row
rowTitleAttributes object false HTML attributes (for example, data attributes) to add to the rowTitle
error boolean false Whether to render this item as an error
errorMessage string false Error message for the row
total boolean false Whether to render this item as a total

SummaryRowItem

Name Type Required Description
iconType string false Name of the icon to be placed next to the title
title string false Label for the row item
valueList Array<SummaryValue> false The value(s) to the row item
actions Array<SummaryAction> false Configurations for action links. If not specified no links will render
attributes object false HTML attributes (for example, data attributes) to add to the row item

SummaryValue

Name Type Required Description
text string true The display value
other string false The display value for the “other” input on a checkbox or radio

SummaryAction

Name Type Required Description
text string true Text for the action link
url string true URL to edit the answer
ariaLabel string false An aria-label to apply to the link if you need it to be more verbose for screen readers
attributes object false HTML attributes (for example, data attributes) to add to the action link
Name Type Required Description
url string true The url for the link to follow the summary
text string true The text for the link to follow the summary
attributes object false HTML attributes (for example, data attributes) to add to the summary 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 %}
            <div class="ons-summary__group">
                {% 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 %}
                    {% if group.groupTitle is defined and group.groupTitle %}
                        <h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
                    {% endif %}
                    {% if group.rows is defined and group.rows %}
                        <table class="ons-summary__items">
                            {% if group.headers is defined and group.headers %}
                                <thead class="ons-u-vh">
                                    <tr>
                                        {% for header in group.headers %}
                                            <th>{{ header }}</th>
                                        {% endfor %}
                                    </tr>
                                </thead>
                            {% endif %}

                            {% 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 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 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 %}
                {% endfor %}
            </div>
        {% endfor %}
    </div>
{% endmacro %}
$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: $summary-col-spacing / 2;
        padding-right: $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"
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    })
}}
Name Type Required Description
summaries Array<Summaries> true An array of summaries
classes string false Classes to add to the summary component
hub boolean false Whether to render the summary in as a hub

Summaries

Name Type Required Description
groups Array<SummaryGroup> true An array of groups within a summary
summaryTitle string false The title for a group of summaries

SummaryGroup

Name Type Required Description
rows Array<SummaryRows> false An array of rows within a group
placeholderText string false A message to be shown as a placeholder if there are no rows in the summary
groupTitle string false The title for a summary within a group
headers Array<SummaryHeaders> false An array of headers to describe the data in the summary
summaryLink Array<SummaryLink> false Settings for the link to appear after the summary

SummaryRow

Name Type Required Description
rowItems Array<SummaryRowItem> true An array of items for this row
rowtitle string false The title for the row
rowTitleAttributes object false HTML attributes (for example, data attributes) to add to the rowTitle
error boolean false Whether to render this item as an error
errorMessage string false Error message for the row
total boolean false Whether to render this item as a total

SummaryRowItem

Name Type Required Description
iconType string false Name of the icon to be placed next to the title
title string false Label for the row item
valueList Array<SummaryValue> false The value(s) to the row item
actions Array<SummaryAction> false Configurations for action links. If not specified no links will render
attributes object false HTML attributes (for example, data attributes) to add to the row item

SummaryValue

Name Type Required Description
text string true The display value
other string false The display value for the “other” input on a checkbox or radio

SummaryAction

Name Type Required Description
text string true Text for the action link
url string true URL to edit the answer
ariaLabel string false An aria-label to apply to the link if you need it to be more verbose for screen readers
attributes object false HTML attributes (for example, data attributes) to add to the action link
Name Type Required Description
url string true The url for the link to follow the summary
text string true The text for the link to follow the summary
attributes object false HTML attributes (for example, data attributes) to add to the summary 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 %}
            <div class="ons-summary__group">
                {% 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 %}
                    {% if group.groupTitle is defined and group.groupTitle %}
                        <h{{ titleSize }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ titleSize }}>
                    {% endif %}
                    {% if group.rows is defined and group.rows %}
                        <table class="ons-summary__items">
                            {% if group.headers is defined and group.headers %}
                                <thead class="ons-u-vh">
                                    <tr>
                                        {% for header in group.headers %}
                                            <th>{{ header }}</th>
                                        {% endfor %}
                                    </tr>
                                </thead>
                            {% endif %}

                            {% 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 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 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 %}
                {% endfor %}
            </div>
        {% endfor %}
    </div>
{% endmacro %}
$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: $summary-col-spacing / 2;
        padding-right: $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