{{ (params.html | safe if params.html else (params.text if params.text else 'Back')) }}
diff --git a/app/templates/components/uk_components/button/README.md b/app/templates/components/uk_components/button/README.md
new file mode 100644
index 000000000..45425bc11
--- /dev/null
+++ b/app/templates/components/uk_components/button/README.md
@@ -0,0 +1,15 @@
+# Button
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+Find out when to use the button component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/button).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/button/#options-example-default) for details.
\ No newline at end of file
diff --git a/app/templates/components/uk_components/button/_button.scss b/app/templates/components/uk_components/button/_button.scss
new file mode 100644
index 000000000..a39a62e29
--- /dev/null
+++ b/app/templates/components/uk_components/button/_button.scss
@@ -0,0 +1,256 @@
+@import "../../settings/all";
+@import "../../tools/all";
+@import "../../helpers/all";
+
+@include govuk-exports("govuk/component/button") {
+ // Primary button variables
+ $govuk-button-colour: #00823b; // sass-lint:disable no-color-literals
+ $govuk-button-hover-colour: govuk-shade($govuk-button-colour, 20%);
+ $govuk-button-shadow-colour: govuk-shade($govuk-button-colour, 60%);
+ $govuk-button-text-colour: govuk-colour("white");
+
+ // Secondary button variables
+ $govuk-secondary-button-colour: govuk-colour("grey-3");
+ $govuk-secondary-button-hover-colour: govuk-shade($govuk-secondary-button-colour, 10%);
+ $govuk-secondary-button-shadow-colour: govuk-shade($govuk-secondary-button-colour, 40%);
+ $govuk-secondary-button-text-colour: govuk-colour("black");
+
+ // Warning button variables
+ $govuk-warning-button-colour: govuk-colour("red");
+ $govuk-warning-button-hover-colour: govuk-shade($govuk-warning-button-colour, 20%);
+ $govuk-warning-button-shadow-colour: govuk-shade($govuk-warning-button-colour, 60%);
+ $govuk-warning-button-text-colour: govuk-colour("white");
+
+ // Because the shadow (s0) is visually 'part of' the button, we need to reduce
+ // the height of the button to compensate by adjusting its padding (s1) and
+ // increase the bottom margin to include it (s2).
+ $button-shadow-size: $govuk-border-width-form-element;
+
+ .govuk-button {
+ @include govuk-font($size: 19, $line-height: 19px);
+ @include govuk-focusable;
+
+ box-sizing: border-box;
+ display: inline-block;
+ position: relative;
+ width: 100%;
+ margin-top: 0;
+ @include govuk-responsive-margin(6, "bottom", $adjustment: $button-shadow-size); // s2
+ padding: (govuk-spacing(2) - $govuk-border-width-form-element - ($button-shadow-size / 2)) govuk-spacing(2); // s1
+ border: $govuk-border-width-form-element solid transparent;
+ border-radius: 0;
+ color: $govuk-button-text-colour;
+ background-color: $govuk-button-colour;
+ box-shadow: 0 $button-shadow-size 0 $govuk-button-shadow-colour; // s0
+ text-align: center;
+ vertical-align: top;
+ cursor: pointer;
+ -webkit-appearance: none;
+
+ @include govuk-if-ie8 {
+ border-bottom: $button-shadow-size solid $govuk-button-shadow-colour;
+ }
+
+ @include govuk-media-query($from: tablet) {
+ width: auto;
+ }
+
+ // Ensure that any global link styles are overridden
+ &:link,
+ &:visited,
+ &:active,
+ &:hover {
+ color: $govuk-button-text-colour;
+ text-decoration: none;
+ }
+
+ // alphagov/govuk_template includes a specific a:link:focus selector
+ // designed to make unvisited links a slightly darker blue when focussed, so
+ // we need to override the text colour for that combination of selectors so
+ // so that unvisited links styled as buttons do not end up with dark blue
+ // text when focussed.
+ @include govuk-compatibility(govuk_template) {
+ &:link:focus {
+ color: $govuk-button-text-colour;
+ }
+ }
+
+ // Fix unwanted button padding in Firefox
+ &::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+ }
+
+ &:hover,
+ &:focus {
+ background-color: $govuk-button-hover-colour;
+ }
+
+ &:active {
+ top: $button-shadow-size;
+ box-shadow: none;
+
+ @include govuk-if-ie8 {
+ border-bottom-width: 0;
+ }
+ }
+
+ // The following adjustments do not work for as
+ // non-container elements cannot include pseudo elements (i.e. ::before).
+
+ // Use a pseudo element to expand the click target area to include the
+ // button's shadow as well, in case users try to click it.
+ &::before {
+ content: "";
+ display: block;
+
+ position: absolute;
+
+ top: -$govuk-border-width-form-element;
+ right: -$govuk-border-width-form-element;
+ bottom: -($govuk-border-width-form-element + $button-shadow-size);
+ left: -$govuk-border-width-form-element;
+
+ background: transparent;
+ }
+
+ // When the button is active it is shifted down by $button-shadow-size to
+ // denote a 'pressed' state. If the user happened to click at the very top
+ // of the button, their mouse is no longer over the button (because it has
+ // 'moved beneath them') and so the click event is not fired.
+ //
+ // This corrects that by shifting the top of the pseudo element so that it
+ // continues to cover the area that the user originally clicked, which means
+ // the click event is still fired.
+ //
+ // π
+ &:active::before {
+ top: -($govuk-border-width-form-element + $button-shadow-size);
+ }
+ }
+
+ .govuk-button--disabled,
+ .govuk-button[disabled="disabled"],
+ .govuk-button[disabled] {
+ opacity: (.5);
+
+ &:hover {
+ background-color: $govuk-button-colour;
+ cursor: default;
+ }
+
+ &:focus {
+ outline: none;
+ }
+
+ &:active {
+ top: 0;
+ box-shadow: 0 $button-shadow-size 0 $govuk-button-shadow-colour; // s0
+ @include govuk-if-ie8 {
+ border-bottom: $button-shadow-size solid $govuk-button-shadow-colour; // s0
+ }
+ }
+ }
+
+ .govuk-button--secondary {
+ background-color: $govuk-secondary-button-colour;
+ box-shadow: 0 $button-shadow-size 0 $govuk-secondary-button-shadow-colour;
+
+ &,
+ &:link,
+ &:visited,
+ &:active,
+ &:hover {
+ color: $govuk-secondary-button-text-colour;
+ }
+
+ // alphagov/govuk_template includes a specific a:link:focus selector
+ // designed to make unvisited links a slightly darker blue when focussed, so
+ // we need to override the text colour for that combination of selectors so
+ // so that unvisited links styled as buttons do not end up with dark blue
+ // text when focussed.
+ @include govuk-compatibility(govuk_template) {
+ &:link:focus {
+ color: $govuk-secondary-button-text-colour;
+ }
+ }
+
+ &:hover,
+ &:focus {
+ background-color: $govuk-secondary-button-hover-colour;
+
+ &[disabled] {
+ background-color: $govuk-secondary-button-colour;
+ }
+ }
+ }
+
+ .govuk-button--warning {
+ background-color: $govuk-warning-button-colour;
+ box-shadow: 0 $button-shadow-size 0 $govuk-warning-button-shadow-colour;
+
+ &,
+ &:link,
+ &:visited,
+ &:active,
+ &:hover {
+ color: $govuk-warning-button-text-colour;
+ }
+
+ // alphagov/govuk_template includes a specific a:link:focus selector
+ // designed to make unvisited links a slightly darker blue when focussed, so
+ // we need to override the text colour for that combination of selectors so
+ // so that unvisited links styled as buttons do not end up with dark blue
+ // text when focussed.
+ @include govuk-compatibility(govuk_template) {
+ &:link:focus {
+ color: $govuk-warning-button-text-colour;
+ }
+ }
+
+ &:hover,
+ &:focus {
+ background-color: $govuk-warning-button-hover-colour;
+
+ &[disabled] {
+ background-color: $govuk-warning-button-colour;
+ }
+ }
+ }
+
+ .govuk-button--start {
+ @include govuk-typography-weight-bold;
+ @include govuk-typography-responsive($size: 24, $override-line-height: 1);
+
+ min-height: auto;
+ padding-top: govuk-spacing(2) - $govuk-border-width-form-element;
+ padding-right: govuk-spacing(7);
+ padding-bottom: govuk-spacing(2) - $govuk-border-width-form-element;
+ padding-left: govuk-spacing(3);
+
+ background-image: govuk-image-url("icon-pointer.png");
+ background-repeat: no-repeat;
+ background-position: 100% 50%;
+
+ @include govuk-device-pixel-ratio {
+ background-image: govuk-image-url("icon-pointer-2x.png");
+ background-size: 30px 19px;
+ }
+ }
+
+ // Begin adjustments for font baseline offset
+ // These should be removed when the font is updated with the correct baseline
+ // For the 1px addition please see https://github.com/alphagov/govuk-frontend/pull/365#discussion_r154349428
+
+ $offset: 2;
+
+ .govuk-button {
+ padding-top: (govuk-spacing(2) - $govuk-border-width-form-element - ($button-shadow-size / 2) + $offset); // s1
+ padding-bottom: (govuk-spacing(2) - $govuk-border-width-form-element - ($button-shadow-size / 2) - $offset + 1); // s1
+ }
+
+ .govuk-button--start {
+ padding-top: (govuk-spacing(2) - $govuk-border-width-form-element - ($button-shadow-size / 2) + $offset); // s1
+ padding-bottom: (govuk-spacing(2) - $govuk-border-width-form-element - ($button-shadow-size / 2) - $offset + 1); // s1
+ }
+}
diff --git a/app/templates/components/uk_components/button/macro-options.json b/app/templates/components/uk_components/button/macro-options.json
new file mode 100644
index 000000000..1e9b76c27
--- /dev/null
+++ b/app/templates/components/uk_components/button/macro-options.json
@@ -0,0 +1,68 @@
+[
+ {
+ "name": "element",
+ "type": "string",
+ "required": false,
+ "description": "Whether to use an `input`, `button` or `a` element to create the button. In most cases you will not need to set this as it will be configured automatically if you use `href` or `html`."
+ },
+ {
+ "name": "text",
+ "type": "string",
+ "required": true,
+ "description": "If `html` is set, this is not required. Text for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`."
+ },
+ {
+ "name": "html",
+ "type": "string",
+ "required": true,
+ "description": "If `text` is set, this is not required. HTML for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`."
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "required": true,
+ "description": "Name for the `input` or `button`. This has no effect on `a` elements."
+ },
+ {
+ "name": "type",
+ "type": "string",
+ "required": true,
+ "description": "Type of `input` or `button` β `button`, `submit` or `reset`. Defaults to `submit`. This has no effect on `a` elements."
+ },
+ {
+ "name": "value",
+ "type": "string",
+ "required": true,
+ "description": "Value for the `button` tag. This has no effect on `a` or `input` elements."
+ },
+ {
+ "name": "disabled",
+ "type": "boolean",
+ "required": false,
+ "description": "Whether the button should be disabled. For button and input elements, `disabled` and `aria-disabled` attributes will be set automatically."
+ },
+ {
+ "name": "href",
+ "type": "string",
+ "required": false,
+ "description": "The URL that the button should link to. If this is set, `element` will be automatically set to `a` if it has not already been defined."
+ },
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the button component."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the button component."
+ },
+ {
+ "name": "preventDoubleClick",
+ "type": "boolean",
+ "required": false,
+ "description": "Prevent accidental double clicks on submit buttons from submitting forms multiple times"
+ }
+]
\ No newline at end of file
diff --git a/app/templates/components/uk_components/button/macro.njk b/app/templates/components/uk_components/button/macro.njk
new file mode 100644
index 000000000..352d538c5
--- /dev/null
+++ b/app/templates/components/uk_components/button/macro.njk
@@ -0,0 +1,3 @@
+{% macro govukButton(params) %}
+ {%- include "./template.njk" -%}
+{% endmacro %}
diff --git a/app/templates/components/uk_components/button/template.njk b/app/templates/components/uk_components/button/template.njk
new file mode 100644
index 000000000..393112675
--- /dev/null
+++ b/app/templates/components/uk_components/button/template.njk
@@ -0,0 +1,35 @@
+{# Determine type of element to use, if not explicitly set -#}
+
+{% if params.element %}
+ {% set element = params.element | lower %}
+{% else %}
+ {% if params.href %}
+ {% set element = 'a' %}
+ {% else %}
+ {% set element = 'button' %}
+ {% endif %}
+{% endif %}
+
+{#- Define common attributes that we can use across all element types #}
+
+{%- set commonAttributes %} class="govuk-button{% if params.classes %} {{ params.classes }}{% endif %}{% if params.disabled %} govuk-button--disabled{% endif %}"{% for attribute, value in params.attributes %} {{attribute}}="{{value}}"{% endfor %}{% endset %}
+
+{#- Define common attributes we can use for both button and input types #}
+
+{%- set buttonAttributes %}{% if params.name %} name="{{ params.name }}"{% endif %} type="{{ params.type if params.type else 'submit' }}"{% if params.disabled %} disabled="disabled" aria-disabled="true"{% endif %}{% if params.preventDoubleClick %} data-prevent-double-click="true"{% endif %}{% endset %}
+
+{#- Actually create a button... or a link! #}
+
+{%- if element == 'a' %}
+
+ {{ params.html | safe if params.html else params.text }}
+
+
+{%- elseif element == 'button' %}
+
+
+{%- elseif element == 'input' %}
+
+{%- endif %}
diff --git a/app/templates/components/uk_components/checkboxes/README.md b/app/templates/components/uk_components/checkboxes/README.md
new file mode 100644
index 000000000..8f094fa21
--- /dev/null
+++ b/app/templates/components/uk_components/checkboxes/README.md
@@ -0,0 +1,15 @@
+# Checkboxes
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+Find out when to use the checkboxes component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/checkboxes).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/checkboxes/#options-example-default) for details.
\ No newline at end of file
diff --git a/app/templates/components/uk_components/checkboxes/_checkboxes.scss b/app/templates/components/uk_components/checkboxes/_checkboxes.scss
new file mode 100644
index 000000000..86309549f
--- /dev/null
+++ b/app/templates/components/uk_components/checkboxes/_checkboxes.scss
@@ -0,0 +1,310 @@
+@import "../../settings/all";
+@import "../../tools/all";
+@import "../../helpers/all";
+
+@import "../error-message/error-message";
+@import "../fieldset/fieldset";
+@import "../hint/hint";
+@import "../label/label";
+
+@include govuk-exports("govuk/component/checkboxes") {
+
+ $govuk-touch-target-size: 44px;
+ $govuk-checkboxes-size: 40px;
+ $govuk-small-checkboxes-size: 24px;
+ $govuk-checkboxes-label-padding-left-right: govuk-spacing(3);
+
+ .govuk-checkboxes__item {
+ @include govuk-font($size: 19);
+
+ display: block;
+ position: relative;
+
+ min-height: $govuk-checkboxes-size;
+
+ margin-bottom: govuk-spacing(2);
+ padding-left: $govuk-checkboxes-size;
+
+ clear: left;
+ }
+
+ .govuk-checkboxes__item:last-child,
+ .govuk-checkboxes__item:last-of-type {
+ margin-bottom: 0;
+ }
+
+ .govuk-checkboxes__input {
+ $input-offset: ($govuk-touch-target-size - $govuk-checkboxes-size) / 2;
+
+ cursor: pointer;
+
+ // IE8 doesnβt support pseudo-elements, so we donβt want to hide native
+ // elements there.
+ @include govuk-not-ie8 {
+ position: absolute;
+
+ z-index: 1;
+ top: $input-offset * -1;
+ left: $input-offset * -1;
+
+ width: $govuk-touch-target-size;
+ height: $govuk-touch-target-size;
+ margin: 0;
+
+ opacity: 0;
+ }
+
+ @include govuk-if-ie8 {
+ margin-top: 10px;
+ margin-right: $govuk-checkboxes-size / -2;
+ margin-left: $govuk-checkboxes-size / -2;
+ float: left;
+
+ // add focus outline to input
+ &:focus {
+ outline: $govuk-focus-width solid $govuk-focus-colour;
+ }
+ }
+ }
+
+ .govuk-checkboxes__label {
+ display: inline-block;
+ margin-bottom: 0;
+ padding: 8px $govuk-checkboxes-label-padding-left-right govuk-spacing(1);
+ cursor: pointer;
+ // remove 300ms pause on mobile
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ }
+
+ // [ ] Check box
+ .govuk-checkboxes__label::before {
+ content: "";
+ box-sizing: border-box;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: $govuk-checkboxes-size;
+ height: $govuk-checkboxes-size;
+ border: $govuk-border-width-form-element solid currentColor;
+ background: transparent;
+ }
+
+ // β Check mark
+ //
+ // The check mark is a box with a border on the left and bottom side (βββ),
+ // rotated 45 degrees
+ .govuk-checkboxes__label::after {
+ content: "";
+
+ position: absolute;
+ top: 11px;
+ left: 9px;
+ width: 18px;
+ height: 7px;
+
+ -webkit-transform: rotate(-45deg);
+
+ -ms-transform: rotate(-45deg);
+
+ transform: rotate(-45deg);
+ border: solid;
+ border-width: 0 0 $govuk-border-width $govuk-border-width;
+ // Fix bug in IE11 caused by transform rotate (-45deg).
+ // See: alphagov/govuk_elements/issues/518
+ border-top-color: transparent;
+
+ opacity: 0;
+
+ background: transparent;
+ }
+
+ .govuk-checkboxes__hint {
+ display: block;
+ padding-right: $govuk-checkboxes-label-padding-left-right;
+ padding-left: $govuk-checkboxes-label-padding-left-right;
+ }
+
+ // Focused state
+ .govuk-checkboxes__input:focus + .govuk-checkboxes__label::before {
+ // Since box-shadows are removed when users customise their colours, we set
+ // a transparent outline that is shown instead.
+ // https://accessibility.blog.gov.uk/2017/03/27/how-users-change-colours-on-websites/
+ outline: $govuk-focus-width solid transparent;
+ outline-offset: $govuk-focus-width;
+ box-shadow: 0 0 0 $govuk-focus-width $govuk-focus-colour;
+ }
+
+ // Selected state
+ .govuk-checkboxes__input:checked + .govuk-checkboxes__label::after {
+ opacity: 1;
+ }
+
+ // Disabled state
+ .govuk-checkboxes__input:disabled,
+ .govuk-checkboxes__input:disabled + .govuk-checkboxes__label {
+ cursor: default;
+ }
+
+ .govuk-checkboxes__input:disabled + .govuk-checkboxes__label {
+ opacity: .5;
+ }
+
+ // =========================================================
+ // Conditional reveals
+ // =========================================================
+
+ $conditional-border-width: $govuk-border-width-mobile;
+ // Calculate the amount of padding needed to keep the border centered against the checkbox.
+ $conditional-border-padding: ($govuk-checkboxes-size / 2) - ($conditional-border-width / 2);
+ // Move the border centered with the checkbox
+ $conditional-margin-left: $conditional-border-padding;
+ // Move the contents of the conditional inline with the label
+ $conditional-padding-left: $conditional-border-padding + $govuk-checkboxes-label-padding-left-right;
+
+ .govuk-checkboxes__conditional {
+ @include govuk-responsive-margin(4, "bottom");
+ margin-left: $conditional-margin-left;
+ padding-left: $conditional-padding-left;
+ border-left: $conditional-border-width solid $govuk-border-colour;
+
+ .js-enabled &--hidden {
+ display: none;
+ }
+
+ & > :last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ // =========================================================
+ // Small checkboxes
+ // =========================================================
+
+ .govuk-checkboxes--small {
+
+ $input-offset: ($govuk-touch-target-size - $govuk-small-checkboxes-size) / 2;
+ $label-offset: $govuk-touch-target-size - $input-offset;
+
+ .govuk-checkboxes__item {
+ @include govuk-clearfix;
+ min-height: 0;
+ margin-bottom: 0;
+ padding-left: $label-offset;
+ float: left;
+ }
+
+ // Shift the touch target into the left margin so that the visible edge of
+ // the control is aligned
+ //
+ // βWhat colours do you like?
+ // ββββββ
+ // ββ[] β Purple
+ // βββ²βββ
+ // β²βββ Check box pseudo element, aligned with margin
+ // ββββ Touch target (invisible input), shifted into the margin
+ .govuk-checkboxes__input {
+ @include govuk-not-ie8 {
+ left: $input-offset * -1;
+ }
+
+ @include govuk-if-ie8 {
+ margin-left: $govuk-small-checkboxes-size * -1;
+ }
+ }
+
+ // Adjust the size and position of the label.
+ //
+ // Unlike larger checkboxes, we also have to float the label in order to
+ // 'shrink' it, preventing the hover state from kicking in across the full
+ // width of the parent element.
+ .govuk-checkboxes__label {
+ margin-top: -2px;
+ padding: 13px govuk-spacing(3) 13px 1px;
+ float: left;
+
+ @include govuk-media-query($from: tablet) {
+ padding: 11px govuk-spacing(3) 10px 1px;
+ }
+ }
+
+ // [ ] Check box
+ //
+ // Reduce the size of the check box [1], vertically center it within the
+ // touch target [2]
+ .govuk-checkboxes__label::before {
+ top: $input-offset - $govuk-border-width-form-element; // 2
+ width: $govuk-small-checkboxes-size; // 1
+ height: $govuk-small-checkboxes-size; // 1
+ }
+
+ // β Check mark
+ //
+ // Reduce the size of the check mark and re-align within the checkbox
+ .govuk-checkboxes__label::after {
+ top: 15px;
+ left: 6px;
+ width: 9px;
+ height: 3.5px;
+ border-width: 0 0 3px 3px;
+ }
+
+ // Fix position of hint with small checkboxes
+ //
+ // Do not use hints with small checkboxes β because they're within the input
+ // wrapper they trigger the hover state, but clicking them doesn't actually
+ // activate the control.
+ //
+ // (If you do use them, they won't look completely broken... but seriously,
+ // don't use them)
+ .govuk-checkboxes__hint {
+ padding: 0;
+ clear: both;
+ }
+
+ // Align conditional reveals with small checkboxes
+ .govuk-checkboxes__conditional {
+ $margin-left: ($govuk-small-checkboxes-size / 2) - ($conditional-border-width / 2);
+ margin-left: $margin-left;
+ padding-left: $label-offset - ($margin-left + $conditional-border-width);
+ clear: both;
+ }
+
+ // Hover state for small checkboxes.
+ //
+ // We use a hover state for small checkboxes because the touch target size
+ // is so much larger than their visible size, and so we need to provide
+ // feedback to the user as to which checkbox they will select when their
+ // cursor is outside of the visible area.
+ .govuk-checkboxes__item:hover .govuk-checkboxes__input:not(:disabled) + .govuk-checkboxes__label::before {
+ box-shadow: 0 0 0 $govuk-hover-width $govuk-hover-colour;
+ }
+
+ // Because we've overridden the border-shadow provided by the focus state,
+ // we need to redefine that too.
+ //
+ // We use two box shadows, one that restores the original focus state [1]
+ // and another that then applies the hover state [2].
+ .govuk-checkboxes__item:hover .govuk-checkboxes__input:focus + .govuk-checkboxes__label::before {
+ // sass-lint:disable indentation
+ box-shadow: 0 0 0 $govuk-focus-width $govuk-focus-colour, // 1
+ 0 0 0 $govuk-hover-width $govuk-hover-colour; // 2
+ }
+
+ // For devices that explicitly don't support hover, don't provide a hover
+ // state (e.g. on touch devices like iOS).
+ //
+ // We can't use `@media (hover: hover)` because we wouldn't get the hover
+ // state in browsers that don't support `@media (hover)` (like Internet
+ // Explorer) β so we have to 'undo' the hover state instead.
+ @media (hover: none), (pointer: coarse) {
+ .govuk-checkboxes__item:hover .govuk-checkboxes__input:not(:disabled) + .govuk-checkboxes__label::before {
+ box-shadow: initial;
+ }
+
+ .govuk-checkboxes__item:hover .govuk-checkboxes__input:focus + .govuk-checkboxes__label::before {
+ box-shadow: 0 0 0 $govuk-focus-width $govuk-focus-colour;
+ }
+ }
+ }
+}
diff --git a/app/templates/components/uk_components/checkboxes/macro-options.json b/app/templates/components/uk_components/checkboxes/macro-options.json
new file mode 100644
index 000000000..db2970c10
--- /dev/null
+++ b/app/templates/components/uk_components/checkboxes/macro-options.json
@@ -0,0 +1,149 @@
+[
+ {
+ "name": "describedBy",
+ "type": "string",
+ "required": false,
+ "description": "One or more element IDs to add to the input `aria-describedby` attribute without a fieldset, used to provide additional descriptive information for screenreader users."
+ },
+ {
+ "name": "fieldset",
+ "type": "object",
+ "required": false,
+ "description": "Options for the fieldset component (e.g. legend).",
+ "isComponent": true
+ },
+ {
+ "name": "hint",
+ "type": "object",
+ "required": false,
+ "description": "Options for the hint component (e.g. text).",
+ "isComponent": true
+ },
+ {
+ "name": "errorMessage",
+ "type": "object",
+ "required": false,
+ "description": "Options for the errorMessage component (e.g. text).",
+ "isComponent": true
+ },
+ {
+ "name": "formGroup",
+ "type": "object",
+ "required": false,
+ "description": "Options for the form-group wrapper",
+ "params": [
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the form group (e.g. to show error state for the whole group)"
+ }
+ ]
+ },
+ {
+ "name": "idPrefix",
+ "type": "string",
+ "required": false,
+ "description": "String to prefix id for each checkbox item if no id is specified on each item. If not passed, fall back to using the name option instead."
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "required": true,
+ "description": "Name attribute for all checkbox items."
+ },
+ {
+ "name": "items",
+ "type": "array",
+ "required": true,
+ "description": "Array of checkbox items objects.",
+ "params": [
+ {
+ "name": "text",
+ "type": "string",
+ "required": true,
+ "description": "If `html` is set, this is not required. Text to use within each checkbox item label. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "html",
+ "type": "string",
+ "required": true,
+ "description": "If `text` is set, this is not required. HTML to use within each checkbox item label. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "id",
+ "type": "string",
+ "required": false,
+ "description": "Specific id attribute for the checkbox item. If omitted, then idPrefix option will be applied."
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "required": true,
+ "description": "Specific name for the checkbox item. If omitted, then component global `name` string will be applied."
+ },
+ {
+ "name": "value",
+ "type": "string",
+ "required": true,
+ "description": "Value for the checkbox input."
+ },
+ {
+ "name": "label",
+ "type": "object",
+ "required": false,
+ "description": "Provide attributes and classes to each checkbox item label.",
+ "isComponent": true
+ },
+ {
+ "name": "hint",
+ "type": "object",
+ "required": false,
+ "description": "Provide hint to each checkbox item.",
+ "isComponent": true
+ },
+ {
+ "name": "checked",
+ "type": "boolean",
+ "required": false,
+ "description": "If true, checkbox will be checked."
+ },
+ {
+ "name": "conditional",
+ "type": "boolean",
+ "required": false,
+ "description": "If true, content provided will be revealed when the item is checked."
+ },
+ {
+ "name": "conditional.html",
+ "type": "string",
+ "required": false,
+ "description": "Provide content for the conditional reveal."
+ },
+ {
+ "name": "disabled",
+ "type": "boolean",
+ "required": false,
+ "description": "If true, checkbox will be disabled."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the checkbox input tag."
+ }
+ ]
+ },
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the checkboxes container."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the anchor tag."
+ }
+]
\ No newline at end of file
diff --git a/app/templates/components/uk_components/checkboxes/macro.njk b/app/templates/components/uk_components/checkboxes/macro.njk
new file mode 100644
index 000000000..e023534a4
--- /dev/null
+++ b/app/templates/components/uk_components/checkboxes/macro.njk
@@ -0,0 +1,3 @@
+{% macro govukCheckboxes(params) %}
+ {%- include "./template.njk" -%}
+{% endmacro %}
diff --git a/app/templates/components/uk_components/checkboxes/template.njk b/app/templates/components/uk_components/checkboxes/template.njk
new file mode 100644
index 000000000..9a12be65c
--- /dev/null
+++ b/app/templates/components/uk_components/checkboxes/template.njk
@@ -0,0 +1,109 @@
+{% from "../error-message/macro.njk" import govukErrorMessage -%}
+{% from "../fieldset/macro.njk" import govukFieldset %}
+{% from "../hint/macro.njk" import govukHint %}
+{% from "../label/macro.njk" import govukLabel %}
+
+{#- If an id 'prefix' is not passed, fall back to using the name attribute
+ instead. We need this for error messages and hints as well -#}
+{% set idPrefix = params.idPrefix if params.idPrefix else params.name %}
+
+{#- a record of other elements that we need to associate with the input using
+ aria-describedby β for example hints or error messages -#}
+{% set describedBy = params.describedBy if params.describedBy else "" %}
+{% if params.fieldset.describedBy %}
+ {% set describedBy = params.fieldset.describedBy %}
+{% endif %}
+
+{% set isConditional = false %}
+{% for item in params.items %}
+ {% if item.conditional %}
+ {% set isConditional = true %}
+ {% endif %}
+{% endfor %}
+
+{#- fieldset is false by default -#}
+{% set hasFieldset = true if params.fieldset else false %}
+
+{#- Capture the HTML so we can optionally nest it in a fieldset -#}
+{% set innerHtml %}
+{% if params.hint %}
+ {% set hintId = idPrefix + '-hint' %}
+ {% set describedBy = describedBy + ' ' + hintId if describedBy else hintId %}
+ {{ govukHint({
+ id: hintId,
+ classes: params.hint.classes,
+ attributes: params.hint.attributes,
+ html: params.hint.html,
+ text: params.hint.text
+ }) | indent(2) | trim }}
+{% endif %}
+{% if params.errorMessage %}
+ {% set errorId = idPrefix + '-error' %}
+ {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %}
+ {{ govukErrorMessage({
+ id: errorId,
+ classes: params.errorMessage.classes,
+ attributes: params.errorMessage.attributes,
+ html: params.errorMessage.html,
+ text: params.errorMessage.text,
+ visuallyHiddenText: params.errorMessage.visuallyHiddenText
+ }) | indent(2) | trim }}
+{% endif %}
+
+ {% for item in params.items %}
+ {% set id = item.id if item.id else idPrefix + "-" + loop.index %}
+ {% set name = item.name if item.name else params.name %}
+ {% set conditionalId = "conditional-" + id %}
+ {% set hasHint = true if item.hint.text or item.hint.html %}
+ {% set itemHintId = id + "-item-hint" if hasHint else "" %}
+ {% set itemDescribedBy = describedBy if not hasFieldset else "" %}
+ {% set itemDescribedBy = (itemDescribedBy + " " + itemHintId) | trim %}
+
diff --git a/app/templates/components/uk_components/details/README.md b/app/templates/components/uk_components/details/README.md
new file mode 100644
index 000000000..c44486c73
--- /dev/null
+++ b/app/templates/components/uk_components/details/README.md
@@ -0,0 +1,15 @@
+# Details
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+Find out when to use the details component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/details).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/details/#options-example-default) for details.
\ No newline at end of file
diff --git a/app/templates/components/uk_components/details/_details.scss b/app/templates/components/uk_components/details/_details.scss
new file mode 100644
index 000000000..44c80ad58
--- /dev/null
+++ b/app/templates/components/uk_components/details/_details.scss
@@ -0,0 +1,89 @@
+@import "../../settings/all";
+@import "../../tools/all";
+@import "../../helpers/all";
+
+@include govuk-exports("govuk/component/details") {
+
+ .govuk-details {
+ @include govuk-font($size: 19);
+ @include govuk-text-colour;
+ @include govuk-responsive-margin(6, "bottom");
+
+ display: block;
+ }
+
+ .govuk-details__summary {
+ // Make the focus outline shrink-wrap the text content of the summary
+ display: inline-block;
+
+ // Absolutely position the marker against this element
+ position: relative;
+
+ margin-bottom: govuk-spacing(1);
+
+ // Allow for absolutely positioned marker and align with disclosed text
+ padding-left: govuk-spacing(4) + $govuk-border-width;
+
+ // Style the summary to look like a link...
+ color: $govuk-link-colour;
+ cursor: pointer;
+ }
+
+ // ...but only underline the text, not the arrow
+ .govuk-details__summary-text {
+ text-decoration: underline;
+ }
+
+ .govuk-details__summary:hover {
+ color: $govuk-link-hover-colour;
+ }
+
+ .govuk-details__summary:focus {
+ // -1px offset fixes gap between background and outline in Firefox
+ outline: ($govuk-focus-width + 1px) solid $govuk-focus-colour;
+ outline-offset: -1px;
+ // When focussed, the text colour needs to be darker to ensure that colour
+ // contrast is still acceptable
+ color: $govuk-focus-text-colour;
+ background: $govuk-focus-colour;
+ }
+
+ // Remove the default details marker so we can style our own consistently and
+ // ensure it displays in Firefox (see implementation.md for details)
+ .govuk-details__summary::-webkit-details-marker {
+ display: none;
+ }
+
+ // Append our own open / closed marker using a pseudo-element
+ .govuk-details__summary:before {
+ content: "";
+ position: absolute;
+
+ top: 0;
+ bottom: 0;
+ left: 0;
+
+ margin: auto;
+
+ @include govuk-shape-arrow($direction: right, $base: 14px);
+
+ .govuk-details[open] > & {
+ @include govuk-shape-arrow($direction: down, $base: 14px);
+ }
+ }
+
+ .govuk-details__text {
+ padding: govuk-spacing(3);
+ padding-left: govuk-spacing(4);
+ border-left: $govuk-border-width solid $govuk-border-colour;
+ }
+
+ .govuk-details__text p {
+ margin-top: 0;
+ margin-bottom: govuk-spacing(4);
+ }
+
+ .govuk-details__text > :last-child {
+ margin-bottom: 0;
+ }
+}
diff --git a/app/templates/components/uk_components/details/macro-options.json b/app/templates/components/uk_components/details/macro-options.json
new file mode 100644
index 000000000..8ad052b6d
--- /dev/null
+++ b/app/templates/components/uk_components/details/macro-options.json
@@ -0,0 +1,50 @@
+[
+ {
+ "name": "summaryText",
+ "type": "string",
+ "required": true,
+ "description": "If `summmaryHtml` is set, this is not required. Text to use within the summary element (the visible part of the details element). If `summaryHtml` is provided, the `summaryText` argument will be ignored."
+ },
+ {
+ "name": "summaryHtml",
+ "type": "string",
+ "required": true,
+ "description": "If `summmaryText` is set, this is not required. HTML to use within the summary element (the visible part of the details element). If `summaryHtml` is provided, the `summaryText` argument will be ignored."
+ },
+ {
+ "name": "text",
+ "type": "string",
+ "required": true,
+ "description": "If `html` is set, this is not required. Text to use within the disclosed part of the details element. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "html",
+ "type": "string",
+ "required": true,
+ "description": "If `text` is set, this is not required. HTML to use within the disclosed part of the details element. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "id",
+ "type": "string",
+ "required": false,
+ "description": "Id to add to the details element."
+ },
+ {
+ "name": "open",
+ "type": "boolean",
+ "required": false,
+ "description": "If true, details element will be expanded."
+ },
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the `` element."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the `` element."
+ }
+]
\ No newline at end of file
diff --git a/app/templates/components/uk_components/details/macro.njk b/app/templates/components/uk_components/details/macro.njk
new file mode 100644
index 000000000..e53969983
--- /dev/null
+++ b/app/templates/components/uk_components/details/macro.njk
@@ -0,0 +1,3 @@
+{% macro govukDetails(params) %}
+ {%- include "./template.njk" -%}
+{% endmacro %}
diff --git a/app/templates/components/uk_components/details/template.njk b/app/templates/components/uk_components/details/template.njk
new file mode 100644
index 000000000..999a7ec0d
--- /dev/null
+++ b/app/templates/components/uk_components/details/template.njk
@@ -0,0 +1,10 @@
+
+
+
+ {{ params.summaryHtml | safe if params.summaryHtml else params.summaryText }}
+
+
+
+
diff --git a/app/templates/components/uk_components/hint/README.md b/app/templates/components/uk_components/hint/README.md
new file mode 100644
index 000000000..e87a00ab4
--- /dev/null
+++ b/app/templates/components/uk_components/hint/README.md
@@ -0,0 +1,15 @@
+# Hint
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+The label component is used in other input components, to see an example of it in use see the [text input component](https://design-system.service.gov.uk/components/text-input/#using-hint-text).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/file-upload/#options-example-default--hint) for details.
\ No newline at end of file
diff --git a/app/templates/components/uk_components/hint/_hint.scss b/app/templates/components/uk_components/hint/_hint.scss
new file mode 100644
index 000000000..7dab10c46
--- /dev/null
+++ b/app/templates/components/uk_components/hint/_hint.scss
@@ -0,0 +1,50 @@
+@import "../../settings/all";
+@import "../../tools/all";
+@import "../../helpers/all";
+
+@include govuk-exports("govuk/component/hint") {
+ .govuk-hint {
+ @include govuk-font($size: 19);
+
+ display: block;
+
+ margin-bottom: govuk-spacing(3);
+
+ color: $govuk-secondary-text-colour;
+ }
+
+ // Reduces margin-bottom of hint when used after the default label (no class)
+ // or govuk-label--s for better vertical alignment.
+
+ // This adjustment will not work when the label is inside the
, however it
+ // is unlikely that the default or govuk-label--s class would be used in this
+ // case.
+
+ // This adjustment will not work in browsers that do not support :not().
+ // Users with these browsers will see the default size margin (5px larger).
+
+ .govuk-label:not(.govuk-label--m):not(.govuk-label--l):not(.govuk-label--xl) + .govuk-hint {
+ margin-bottom: govuk-spacing(2);
+ }
+
+ // Reduces margin-bottom of hint when used after the default legend (no class)
+ // or govuk-fieldset__legend--s for better vertical alignment.
+
+ // This adjustment will not work when the legend is outside the
, however
+ // it is unlikely that the default or govuk-fieldset__legend--s class would be
+ // used in this case.
+
+ // This adjustment will not work in browsers that do not support :not().
+ // Users with these browsers will see the default size margin (5px larger).
+
+ .govuk-fieldset__legend:not(.govuk-fieldset__legend--m):not(.govuk-fieldset__legend--l):not(.govuk-fieldset__legend--xl) + .govuk-hint {
+ margin-bottom: govuk-spacing(2);
+ }
+
+ // Reduces visual spacing of legend when there is a hint
+
+ .govuk-fieldset__legend + .govuk-hint,
+ .govuk-fieldset__legend + .govuk-hint {
+ margin-top: -(govuk-spacing(1));
+ }
+}
diff --git a/app/templates/components/uk_components/hint/macro-options.json b/app/templates/components/uk_components/hint/macro-options.json
new file mode 100644
index 000000000..2e066ddbe
--- /dev/null
+++ b/app/templates/components/uk_components/hint/macro-options.json
@@ -0,0 +1,32 @@
+[
+ {
+ "name": "text",
+ "type": "string",
+ "required": true,
+ "description": "If `html` is set, this is not required. Text to use within the hint. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "html",
+ "type": "string",
+ "required": true,
+ "description": "If `text` is set, this is not required. HTML to use within the hint. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "id",
+ "type": "string",
+ "required": true,
+ "description": "Optional id attribute to add to the hint span tag."
+ },
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the hint span tag."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the hint span tag."
+ }
+]
\ No newline at end of file
diff --git a/app/templates/components/uk_components/hint/macro.njk b/app/templates/components/uk_components/hint/macro.njk
new file mode 100644
index 000000000..e0a639d75
--- /dev/null
+++ b/app/templates/components/uk_components/hint/macro.njk
@@ -0,0 +1,3 @@
+{% macro govukHint(params) %}
+ {%- include "./template.njk" -%}
+{% endmacro %}
diff --git a/app/templates/components/uk_components/hint/template.njk b/app/templates/components/uk_components/hint/template.njk
new file mode 100644
index 000000000..58350dca0
--- /dev/null
+++ b/app/templates/components/uk_components/hint/template.njk
@@ -0,0 +1,4 @@
+
+ {{ params.html | safe if params.html else params.text }}
+
diff --git a/app/templates/components/uk_components/input/README.md b/app/templates/components/uk_components/input/README.md
new file mode 100644
index 000000000..87211de01
--- /dev/null
+++ b/app/templates/components/uk_components/input/README.md
@@ -0,0 +1,15 @@
+# Input
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+Find out when to use the input component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/text-input).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/text-input/#options-example-default) for details.
\ No newline at end of file
diff --git a/app/templates/components/uk_components/input/_input.scss b/app/templates/components/uk_components/input/_input.scss
new file mode 100644
index 000000000..1dc1f06d3
--- /dev/null
+++ b/app/templates/components/uk_components/input/_input.scss
@@ -0,0 +1,77 @@
+@import "../../settings/all";
+@import "../../tools/all";
+@import "../../helpers/all";
+
+@import "../error-message/error-message";
+@import "../hint/hint";
+@import "../label/label";
+
+@include govuk-exports("govuk/component/input") {
+ .govuk-input {
+ @include govuk-font($size: 19);
+ @include govuk-focusable;
+
+ box-sizing: border-box;
+ width: 100%;
+ height: 40px;
+ margin-top: 0;
+
+ padding: govuk-spacing(1);
+ // setting any background-color makes text invisible when changing colours to dark backgrounds in Firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=1335476)
+ // as background-color and color need to always be set together, color should not be set either
+ border: $govuk-border-width-form-element solid $govuk-input-border-colour;
+ border-radius: 0;
+
+ // Disable inner shadow and remove rounded corners
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ }
+
+ .govuk-input::-webkit-outer-spin-button,
+ .govuk-input::-webkit-inner-spin-button {
+ margin: 0;
+ -webkit-appearance: none;
+ }
+
+ .govuk-input[type="number"] {
+ -moz-appearance: textfield;
+ }
+
+ .govuk-input--error {
+ border: $govuk-border-width-form-element-error solid $govuk-error-colour;
+ }
+
+ // The ex measurements are based on the number of W's that can fit inside the input
+ // Extra space is left on the right hand side to allow for the Safari prefill icon
+ // Linear regression estimation based on visual tests: y = 1.76 + 1.81x
+
+ .govuk-input--width-30 {
+ max-width: 56ex + 3ex;
+ }
+
+ .govuk-input--width-20 {
+ max-width: 38ex + 3ex;
+ }
+
+ .govuk-input--width-10 {
+ max-width: 20ex + 3ex;
+ }
+
+ .govuk-input--width-5 {
+ max-width: 10.8ex;
+ }
+
+ .govuk-input--width-4 {
+ max-width: 9ex;
+ }
+
+ .govuk-input--width-3 {
+ max-width: 7.2ex;
+ }
+
+ .govuk-input--width-2 {
+ max-width: 5.4ex;
+ }
+
+}
diff --git a/app/templates/components/uk_components/input/macro-options.json b/app/templates/components/uk_components/input/macro-options.json
new file mode 100644
index 000000000..6bf5e41af
--- /dev/null
+++ b/app/templates/components/uk_components/input/macro-options.json
@@ -0,0 +1,91 @@
+[
+ {
+ "name": "id",
+ "type": "string",
+ "required": true,
+ "description": "The id of the input."
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "required": true,
+ "description": "The name of the input, which is submitted with the form data."
+ },
+ {
+ "name": "type",
+ "type": "string",
+ "required": false,
+ "description": "Type of input control to render. Defaults to \"text\"."
+ },
+ {
+ "name": "value",
+ "type": "string",
+ "required": false,
+ "description": "Optional initial value of the input."
+ },
+ {
+ "name": "describedBy",
+ "type": "string",
+ "required": false,
+ "description": "One or more element IDs to add to the `aria-describedby` attribute, used to provide additional descriptive information for screenreader users."
+ },
+ {
+ "name": "label",
+ "type": "object",
+ "required": true,
+ "description": "Options for the label component.",
+ "isComponent": true
+ },
+ {
+ "name": "hint",
+ "type": "object",
+ "required": false,
+ "description": "Options for the hint component.",
+ "isComponent": true
+ },
+ {
+ "name": "errorMessage",
+ "type": "object",
+ "required": false,
+ "description": "Options for the errorMessage component.",
+ "isComponent": true
+ },
+ {
+ "name": "formGroup",
+ "type": "object",
+ "required": false,
+ "description": "Options for the form-group wrapper",
+ "params": [
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the form group (e.g. to show error state for the whole group)"
+ }
+ ]
+ },
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the input."
+ },
+ {
+ "name": "autocomplete",
+ "type": "string",
+ "required": false,
+ "description": "Attribute to [identify input purpose](https://www.w3.org/WAI/WCAG21/Understanding/identify-input-purpose.html), for instance \"postal-code\" or \"username\". See [autofill](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill) for full list of attributes that can be used."
+ },
+ {
+ "name": "pattern",
+ "type": "string",
+ "required": false,
+ "description": "Attribute to [provide a regular expression pattern](https://www.w3.org/TR/html51/sec-forms.html#the-pattern-attribute), used to match allowed character combinations for the input value."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the anchor tag."
+ }
+]
\ No newline at end of file
diff --git a/app/templates/components/uk_components/input/macro.njk b/app/templates/components/uk_components/input/macro.njk
new file mode 100644
index 000000000..e512c1864
--- /dev/null
+++ b/app/templates/components/uk_components/input/macro.njk
@@ -0,0 +1,3 @@
+{% macro govukInput(params) %}
+ {%- include "./template.njk" -%}
+{% endmacro %}
diff --git a/app/templates/components/uk_components/input/template.njk b/app/templates/components/uk_components/input/template.njk
new file mode 100644
index 000000000..95cbd9aa8
--- /dev/null
+++ b/app/templates/components/uk_components/input/template.njk
@@ -0,0 +1,46 @@
+{% from "../error-message/macro.njk" import govukErrorMessage -%}
+{% from "../hint/macro.njk" import govukHint %}
+{% from "../label/macro.njk" import govukLabel %}
+
+{#- a record of other elements that we need to associate with the input using
+ aria-describedby β for example hints or error messages -#}
+{% set describedBy = params.describedBy if params.describedBy else "" %}
+
diff --git a/app/templates/components/uk_components/inset-text/README.md b/app/templates/components/uk_components/inset-text/README.md
new file mode 100644
index 000000000..b13918cd9
--- /dev/null
+++ b/app/templates/components/uk_components/inset-text/README.md
@@ -0,0 +1,15 @@
+# Inset text
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+Find out when to use the inset text component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/inset-text).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/inset-text/#options-example-default) for details.
\ No newline at end of file
diff --git a/app/templates/components/uk_components/inset-text/_inset-text.scss b/app/templates/components/uk_components/inset-text/_inset-text.scss
new file mode 100644
index 000000000..524dc50c8
--- /dev/null
+++ b/app/templates/components/uk_components/inset-text/_inset-text.scss
@@ -0,0 +1,28 @@
+@import "../../settings/all";
+@import "../../tools/all";
+@import "../../helpers/all";
+
+@include govuk-exports("govuk/component/inset-text") {
+ .govuk-inset-text {
+ @include govuk-font($size: 19);
+ @include govuk-text-colour;
+ padding: govuk-spacing(3);
+ // Margin top intended to collapse
+ // This adds an additional 10px to the paragraph above
+ @include govuk-responsive-margin(6, "top");
+ @include govuk-responsive-margin(6, "bottom");
+
+ clear: both;
+
+ border-left: $govuk-border-width-wide solid $govuk-border-colour;
+
+ > :first-child {
+ margin-top: 0;
+ }
+
+ > :only-child,
+ > :last-child {
+ margin-bottom: 0;
+ }
+ }
+}
diff --git a/app/templates/components/uk_components/inset-text/macro-options.json b/app/templates/components/uk_components/inset-text/macro-options.json
new file mode 100644
index 000000000..da06fae8c
--- /dev/null
+++ b/app/templates/components/uk_components/inset-text/macro-options.json
@@ -0,0 +1,32 @@
+[
+ {
+ "name": "text",
+ "type": "string",
+ "required": true,
+ "description": "If `html` is set, this is not required. Text to use within the back link component. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "html",
+ "type": "string",
+ "required": true,
+ "description": "If `text` is set, this is not required. HTML to use within the back link component. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "id",
+ "type": "string",
+ "required": false,
+ "description": "Id attribute to add to the inset text container."
+ },
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the inset text container."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the inset text container."
+ }
+]
\ No newline at end of file
diff --git a/app/templates/components/uk_components/inset-text/macro.njk b/app/templates/components/uk_components/inset-text/macro.njk
new file mode 100644
index 000000000..935c8a69c
--- /dev/null
+++ b/app/templates/components/uk_components/inset-text/macro.njk
@@ -0,0 +1,3 @@
+{% macro govukInsetText(params) %}
+ {%- include './template.njk' -%}
+{% endmacro %}
diff --git a/app/templates/components/uk_components/inset-text/template.njk b/app/templates/components/uk_components/inset-text/template.njk
new file mode 100644
index 000000000..ade008fed
--- /dev/null
+++ b/app/templates/components/uk_components/inset-text/template.njk
@@ -0,0 +1,4 @@
+
diff --git a/app/templates/components/uk_components/label/README.md b/app/templates/components/uk_components/label/README.md
new file mode 100644
index 000000000..dd2d7b97e
--- /dev/null
+++ b/app/templates/components/uk_components/label/README.md
@@ -0,0 +1,15 @@
+# Label
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+The label component is used in other input components, to see an example of it in use see the [text input component](https://design-system.service.gov.uk/components/text-input/).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/file-upload/#options-example-default--label) for details.
\ No newline at end of file
diff --git a/app/templates/components/uk_components/label/_label.scss b/app/templates/components/uk_components/label/_label.scss
new file mode 100644
index 000000000..bfe400e57
--- /dev/null
+++ b/app/templates/components/uk_components/label/_label.scss
@@ -0,0 +1,45 @@
+@import "../../settings/all";
+@import "../../tools/all";
+@import "../../helpers/all";
+
+@include govuk-exports("govuk/component/label") {
+ .govuk-label {
+ @include govuk-font($size: 19);
+ @include govuk-text-colour;
+
+ display: block;
+
+ margin-bottom: govuk-spacing(1);
+ }
+
+ // Modifiers that make labels look more like their equivalent headings
+
+ .govuk-label--xl {
+ @include govuk-font($size: 48, $weight: bold);
+ margin-bottom: govuk-spacing(3);
+ }
+
+ .govuk-label--l {
+ @include govuk-font($size: 36, $weight: bold);
+ margin-bottom: govuk-spacing(3);
+ }
+
+ .govuk-label--m {
+ @include govuk-font($size: 24, $weight: bold);
+ margin-bottom: govuk-spacing(2);
+ }
+
+ .govuk-label--s {
+ @include govuk-font($size: 19, $weight: bold);
+ }
+
+ // When the label is nested inside a heading, override the heading so that it
+ // does not have a margin. Effectively we want to be able to treat the heading
+ // as if it is not there.
+ //
+ // This breaks BEM conventions because it exists as a parent of the 'block',
+ // so we can't really consider an element.
+ .govuk-label-wrapper {
+ margin: 0;
+ }
+}
diff --git a/app/templates/components/uk_components/label/macro-options.json b/app/templates/components/uk_components/label/macro-options.json
new file mode 100644
index 000000000..2b40a9577
--- /dev/null
+++ b/app/templates/components/uk_components/label/macro-options.json
@@ -0,0 +1,38 @@
+[
+ {
+ "name": "text",
+ "type": "string",
+ "required": true,
+ "description": "If `html` is set, this is not required. Text to use within the label. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "html",
+ "type": "string",
+ "required": true,
+ "description": "If `text` is set, this is not required. HTML to use within the label. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "for",
+ "type": "string",
+ "required": true,
+ "description": "The value of the for attribute, the id of the input the label is associated with."
+ },
+ {
+ "name": "isPageHeading",
+ "type": "boolean",
+ "required": false,
+ "description": "Whether the label also acts as the heading for the page."
+ },
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the label tag."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the label tag."
+ }
+]
\ No newline at end of file
diff --git a/app/templates/components/uk_components/label/macro.njk b/app/templates/components/uk_components/label/macro.njk
new file mode 100644
index 000000000..91f2ed71a
--- /dev/null
+++ b/app/templates/components/uk_components/label/macro.njk
@@ -0,0 +1,3 @@
+{% macro govukLabel(params) %}
+ {%- include "./template.njk" -%}
+{% endmacro %}
diff --git a/app/templates/components/uk_components/label/template.njk b/app/templates/components/uk_components/label/template.njk
new file mode 100644
index 000000000..b740e2b3d
--- /dev/null
+++ b/app/templates/components/uk_components/label/template.njk
@@ -0,0 +1,15 @@
+{% if params.html or params.text %}
+{% set labelHtml %}
+
+{% endset %}
+
+{% if params.isPageHeading %}
+
{{ labelHtml | safe | indent(2) }}
+{% else %}
+{{ labelHtml | safe }}
+{% endif %}
+{% endif %}
diff --git a/app/templates/components/uk_components/radios/README.md b/app/templates/components/uk_components/radios/README.md
new file mode 100644
index 000000000..8a0da19cb
--- /dev/null
+++ b/app/templates/components/uk_components/radios/README.md
@@ -0,0 +1,15 @@
+# Radios
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+Find out when to use the radios component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/radios).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/radios/#options-example-default) for details.
\ No newline at end of file
diff --git a/app/templates/components/uk_components/radios/_radios.scss b/app/templates/components/uk_components/radios/_radios.scss
new file mode 100644
index 000000000..074bb53cc
--- /dev/null
+++ b/app/templates/components/uk_components/radios/_radios.scss
@@ -0,0 +1,348 @@
+@import "../../settings/all";
+@import "../../tools/all";
+@import "../../helpers/all";
+
+@import "../error-message/error-message";
+@import "../fieldset/fieldset";
+@import "../hint/hint";
+@import "../label/label";
+
+@include govuk-exports("govuk/component/radios") {
+
+ $govuk-touch-target-size: 44px;
+ $govuk-radios-size: 40px;
+ $govuk-small-radios-size: 24px;
+ $govuk-radios-label-padding-left-right: govuk-spacing(3);
+ // When the default focus width is used on a curved edge it looks visually smaller.
+ // So for the circular radios we bump the default to make it look visually consistent.
+ $govuk-radios-focus-width: $govuk-focus-width + 1px;
+
+ .govuk-radios__item {
+ @include govuk-font($size: 19);
+
+ display: block;
+ position: relative;
+
+ min-height: $govuk-radios-size;
+
+ margin-bottom: govuk-spacing(2);
+ padding-left: $govuk-radios-size;
+
+ clear: left;
+ }
+
+ .govuk-radios__item:last-child,
+ .govuk-radios__item:last-of-type {
+ margin-bottom: 0;
+ }
+
+ .govuk-radios__input {
+ $input-offset: ($govuk-touch-target-size - $govuk-radios-size) / 2;
+
+ cursor: pointer;
+
+ // IE8 doesnβt support pseudo-elements, so we donβt want to hide native
+ // elements there.
+ @include govuk-not-ie8 {
+ position: absolute;
+
+ z-index: 1;
+ top: $input-offset * -1;
+ left: $input-offset * -1;
+
+ width: $govuk-touch-target-size;
+ height: $govuk-touch-target-size;
+ margin: 0;
+
+ opacity: 0;
+ }
+
+ @include govuk-if-ie8 {
+ margin-top: 10px;
+ margin-right: $govuk-radios-size / -2;
+ margin-left: $govuk-radios-size / -2;
+ float: left;
+
+ // add focus outline to input
+ &:focus {
+ outline: $govuk-focus-width solid $govuk-focus-colour;
+ }
+ }
+ }
+
+ .govuk-radios__label {
+ display: inline-block;
+ margin-bottom: 0;
+ padding: 8px $govuk-radios-label-padding-left-right govuk-spacing(1);
+ cursor: pointer;
+ // remove 300ms pause on mobile
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ }
+
+ // ( ) Radio ring
+ .govuk-radios__label::before {
+ content: "";
+ box-sizing: border-box;
+ position: absolute;
+ top: 0;
+ left: 0;
+
+ width: $govuk-radios-size;
+ height: $govuk-radios-size;
+
+ border: $govuk-border-width-form-element solid currentColor;
+ border-radius: 50%;
+ background: transparent;
+ }
+
+ // β’ Radio button
+ //
+ // We create the 'button' entirely out of 'border' so that they remain
+ // 'filled' even when colours are overridden in the browser.
+ .govuk-radios__label::after {
+ content: "";
+
+ position: absolute;
+ top: govuk-spacing(2);
+ left: govuk-spacing(2);
+
+ width: 0;
+ height: 0;
+
+ border: govuk-spacing(2) solid currentColor;
+ border-radius: 50%;
+ opacity: 0;
+ background: currentColor;
+ }
+
+ .govuk-radios__hint {
+ display: block;
+ padding-right: $govuk-radios-label-padding-left-right;
+ padding-left: $govuk-radios-label-padding-left-right;
+ }
+
+ // Focused state
+ .govuk-radios__input:focus + .govuk-radios__label::before {
+ // Since box-shadows are removed when users customise their colours we set a
+ // transparent outline that is shown instead.
+ // https://accessibility.blog.gov.uk/2017/03/27/how-users-change-colours-on-websites/
+ outline: $govuk-focus-width solid transparent;
+ outline-offset: $govuk-focus-width;
+ box-shadow: 0 0 0 $govuk-radios-focus-width $govuk-focus-colour;
+ }
+
+ // Selected state
+ .govuk-radios__input:checked + .govuk-radios__label::after {
+ opacity: 1;
+ }
+
+ // Disabled state
+ .govuk-radios__input:disabled,
+ .govuk-radios__input:disabled + .govuk-radios__label {
+ cursor: default;
+ }
+
+ .govuk-radios__input:disabled + .govuk-radios__label {
+ opacity: .5;
+ }
+
+ // =========================================================
+ // Inline radios
+ // =========================================================
+
+ .govuk-radios--inline {
+ @include mq ($from: tablet) {
+ @include govuk-clearfix;
+
+ .govuk-radios__item {
+ margin-right: govuk-spacing(4);
+ float: left;
+ clear: none;
+ }
+ }
+
+ // Prevent inline modifier being used with conditional reveals
+ &.govuk-radios--conditional {
+ .govuk-radios__item {
+ margin-right: 0;
+ float: none;
+ }
+ }
+ }
+
+ // =========================================================
+ // Dividers ('or')
+ // =========================================================
+
+ .govuk-radios__divider {
+ $govuk-divider-size: $govuk-radios-size !default;
+ @include govuk-font($size: 19);
+ @include govuk-text-colour;
+ width: $govuk-divider-size;
+ margin-bottom: govuk-spacing(2);
+ text-align: center;
+ }
+
+ // =========================================================
+ // Conditional reveals
+ // =========================================================
+
+ $conditional-border-width: $govuk-border-width-mobile;
+ // Calculate the amount of padding needed to keep the border centered against the radios.
+ $conditional-border-padding: ($govuk-radios-size / 2) - ($conditional-border-width / 2);
+ // Move the border centered with the radios
+ $conditional-margin-left: $conditional-border-padding;
+ // Move the contents of the conditional inline with the label
+ $conditional-padding-left: $conditional-border-padding + $govuk-radios-label-padding-left-right;
+
+ .govuk-radios__conditional {
+ @include govuk-responsive-margin(4, "bottom");
+ margin-left: $conditional-margin-left;
+ padding-left: $conditional-padding-left;
+ border-left: $conditional-border-width solid $govuk-border-colour;
+
+ .js-enabled &--hidden {
+ display: none;
+ }
+
+ & > :last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ // =========================================================
+ // Small checkboxes
+ // =========================================================
+
+ .govuk-radios--small {
+
+ $input-offset: ($govuk-touch-target-size - $govuk-small-radios-size) / 2;
+ $label-offset: $govuk-touch-target-size - $input-offset;
+
+ .govuk-radios__item {
+ @include govuk-clearfix;
+ min-height: 0;
+ margin-bottom: 0;
+ padding-left: $label-offset;
+ float: left;
+ }
+
+ // Shift the touch target into the left margin so that the visible edge of
+ // the control is aligned
+ //
+ // βWhich colour is your favourite?
+ // ββββββ
+ // ββ() β Purple
+ // βββ²βββ
+ // β²βββ Radio pseudo element, aligned with margin
+ // ββββ Touch target (invisible input), shifted into the margin
+ .govuk-radios__input {
+ @include govuk-not-ie8 {
+ left: $input-offset * -1;
+ }
+
+ @include govuk-if-ie8 {
+ margin-left: $govuk-small-radios-size * -1;
+ }
+ }
+
+ // Adjust the size and position of the label.
+ //
+ // Unlike larger radios, we also have to float the label in order to
+ // 'shrink' it, preventing the hover state from kicking in across the full
+ // width of the parent element.
+ .govuk-radios__label {
+ margin-top: -2px;
+ padding: 13px govuk-spacing(3) 13px 1px;
+ float: left;
+
+ @include govuk-media-query($from: tablet) {
+ padding: 11px govuk-spacing(3) 10px 1px;
+ }
+ }
+
+ // ( ) Radio ring
+ //
+ // Reduce the size of the control [1], vertically centering it within the
+ // touch target [2]
+ .govuk-radios__label::before {
+ top: $input-offset - $govuk-border-width-form-element; // 2
+ width: $govuk-small-radios-size; // 1
+ height: $govuk-small-radios-size; // 1
+ }
+
+ // β’ Radio button
+ //
+ // Reduce the size of the 'button' and center it within the ring
+ .govuk-radios__label::after {
+ top: 14px;
+ left: 6px;
+ border-width: 6px;
+ }
+
+ // Fix position of hint with small radios
+ //
+ // Do not use hints with small radios β because they're within the input
+ // wrapper they trigger the hover state, but clicking them doesn't actually
+ // activate the control.
+ //
+ // (If you do use them, they won't look completely broken... but seriously,
+ // don't use them)
+ .govuk-radios__hint {
+ padding: 0;
+ clear: both;
+ pointer-events: none;
+ }
+
+ // Align conditional reveals with small radios
+ .govuk-radios__conditional {
+ $margin-left: ($govuk-small-radios-size / 2) - ($conditional-border-width / 2);
+ margin-left: $margin-left;
+ padding-left: $label-offset - ($margin-left + $conditional-border-width);
+ clear: both;
+ }
+
+ .govuk-radios__divider {
+ width: $govuk-small-radios-size;
+ margin-bottom: govuk-spacing(1);
+ }
+
+ // Hover state for small radios.
+ //
+ // We use a hover state for small radios because the touch target size
+ // is so much larger than their visible size, and so we need to provide
+ // feedback to the user as to which radio they will select when their
+ // cursor is outside of the visible area.
+ .govuk-radios__item:hover .govuk-radios__input:not(:disabled) + .govuk-radios__label::before {
+ box-shadow: 0 0 0 $govuk-hover-width $govuk-hover-colour;
+ }
+
+ // Because we've overridden the border-shadow provided by the focus state,
+ // we need to redefine that too.
+ //
+ // We use two box shadows, one that restores the original focus state [1]
+ // and another that then applies the hover state [2].
+ .govuk-radios__item:hover .govuk-radios__input:focus + .govuk-radios__label::before {
+ // sass-lint:disable indentation
+ box-shadow: 0 0 0 $govuk-radios-focus-width $govuk-focus-colour, // 1
+ 0 0 0 $govuk-hover-width $govuk-hover-colour; // 2
+ }
+
+ // For devices that explicitly don't support hover, don't provide a hover
+ // state (e.g. on touch devices like iOS).
+ //
+ // We can't use `@media (hover: hover)` because we wouldn't get the hover
+ // state in browsers that don't support `@media (hover)` (like Internet
+ // Explorer) β so we have to 'undo' the hover state instead.
+ @media (hover: none), (pointer: coarse) {
+ .govuk-radios__item:hover .govuk-radios__input:not(:disabled) + .govuk-radios__label::before {
+ box-shadow: initial;
+ }
+
+ .govuk-radios__item:hover .govuk-radios__input:focus + .govuk-radios__label::before {
+ box-shadow: 0 0 0 $govuk-radios-focus-width $govuk-focus-colour;
+ }
+ }
+ }
+}
diff --git a/app/templates/components/uk_components/radios/macro-options.json b/app/templates/components/uk_components/radios/macro-options.json
new file mode 100644
index 000000000..e54fc9142
--- /dev/null
+++ b/app/templates/components/uk_components/radios/macro-options.json
@@ -0,0 +1,143 @@
+[
+ {
+ "name": "fieldset",
+ "type": "object",
+ "required": false,
+ "description": "Options for the fieldset component (e.g. legend).",
+ "isComponent": true
+ },
+ {
+ "name": "hint",
+ "type": "object",
+ "required": false,
+ "description": "Options for the hint component (e.g. text).",
+ "isComponent": true
+ },
+ {
+ "name": "errorMessage",
+ "type": "object",
+ "required": false,
+ "description": "Options for the errorMessage component (e.g. text).",
+ "isComponent": true
+ },
+ {
+ "name": "formGroup",
+ "type": "object",
+ "required": false,
+ "description": "Options for the form-group wrapper",
+ "params": [
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the form group (e.g. to show error state for the whole group)"
+ }
+ ]
+ },
+ {
+ "name": "idPrefix",
+ "type": "string",
+ "required": false,
+ "description": "String to prefix id for each checkbox item if no id is specified on each item. If `idPrefix` is not passed, fallback to using the name attribute instead."
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "required": true,
+ "description": "Name attribute for each radio item."
+ },
+ {
+ "name": "items",
+ "type": "array",
+ "required": true,
+ "description": "Array of radio items objects.",
+ "params": [
+ {
+ "name": "text",
+ "type": "string",
+ "required": true,
+ "description": "If `html` is set, this is not required. Text to use within each radio item label. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "html",
+ "type": "string",
+ "required": true,
+ "description": "If `text` is set, this is not required. HTML to use within each radio item label. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "id",
+ "type": "string",
+ "required": false,
+ "description": "Specific id attribute for the radio item. If omitted, then `idPrefix` string will be applied."
+ },
+ {
+ "name": "value",
+ "type": "string",
+ "required": true,
+ "description": "Value for the radio input."
+ },
+ {
+ "name": "label",
+ "type": "object",
+ "required": false,
+ "description": "Provide attributes and classes to each radio item label.",
+ "isComponent": true
+ },
+ {
+ "name": "hint",
+ "type": "object",
+ "required": false,
+ "description": "Provide hint to each checkbox item.",
+ "isComponent": true
+ },
+ {
+ "name": "divider",
+ "type": "string",
+ "required": false,
+ "description": "Divider text to separate radio items, for example the text \"or\"."
+ },
+ {
+ "name": "checked",
+ "type": "boolean",
+ "required": false,
+ "description": "If true, radio will be checked."
+ },
+ {
+ "name": "conditional",
+ "type": "string",
+ "required": false,
+ "description": "If true, content provided will be revealed when the item is checked."
+ },
+ {
+ "name": "conditional.html",
+ "type": "html",
+ "required": false,
+ "description": "Provide content for the conditional reveal."
+ },
+ {
+ "name": "disabled",
+ "type": "boolean",
+ "required": false,
+ "description": "If true, radio will be disabled."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the radio input tag."
+ }
+ ]
+ },
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the radio container."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the radio input tag."
+ }
+]
\ No newline at end of file
diff --git a/app/templates/components/uk_components/radios/macro.njk b/app/templates/components/uk_components/radios/macro.njk
new file mode 100644
index 000000000..67b4d8b89
--- /dev/null
+++ b/app/templates/components/uk_components/radios/macro.njk
@@ -0,0 +1,3 @@
+{% macro govukRadios(params) %}
+ {%- include "./template.njk" -%}
+{% endmacro %}
diff --git a/app/templates/components/uk_components/radios/template.njk b/app/templates/components/uk_components/radios/template.njk
new file mode 100644
index 000000000..5ef8b832c
--- /dev/null
+++ b/app/templates/components/uk_components/radios/template.njk
@@ -0,0 +1,104 @@
+{% from "../error-message/macro.njk" import govukErrorMessage -%}
+{% from "../fieldset/macro.njk" import govukFieldset %}
+{% from "../hint/macro.njk" import govukHint %}
+{% from "../label/macro.njk" import govukLabel %}
+
+{#- If an id 'prefix' is not passed, fall back to using the name attribute
+ instead. We need this for error messages and hints as well -#}
+{% set idPrefix = params.idPrefix if params.idPrefix else params.name %}
+
+{#- a record of other elements that we need to associate with the input using
+ aria-describedby β for example hints or error messages -#}
+{% set describedBy = params.fieldset.describedBy if params.fieldset.describedBy else "" %}
+
+{% set isConditional = false %}
+{% for item in params.items %}
+ {% if item.conditional %}
+ {% set isConditional = true %}
+ {% endif %}
+{% endfor %}
+
+{#- Capture the HTML so we can optionally nest it in a fieldset -#}
+{% set innerHtml %}
+{% if params.hint %}
+ {% set hintId = idPrefix + '-hint' %}
+ {% set describedBy = describedBy + ' ' + hintId if describedBy else hintId %}
+ {{ govukHint({
+ id: hintId,
+ classes: params.hint.classes,
+ attributes: params.hint.attributes,
+ html: params.hint.html,
+ text: params.hint.text
+ }) | indent(2) | trim }}
+{% endif %}
+{% if params.errorMessage %}
+ {% set errorId = idPrefix + '-error' %}
+ {% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %}
+ {{ govukErrorMessage({
+ id: errorId,
+ classes: params.errorMessage.classes,
+ attributes: params.errorMessage.attributes,
+ html: params.errorMessage.html,
+ text: params.errorMessage.text,
+ visuallyHiddenText: params.errorMessage.visuallyHiddenText
+ }) | indent(2) | trim }}
+{% endif %}
+
+ {% for item in params.items %}
+ {% set id = item.id if item.id else idPrefix + "-" + loop.index %}
+ {% set conditionalId = "conditional-" + id %}
+ {%- if item.divider %}
+
{{ item.divider }}
+ {%- else %}
+ {% set hasHint = true if item.hint.text or item.hint.html %}
+ {% set itemHintId = id + '-item-hint' %}
+
diff --git a/app/templates/components/uk_components/skip-link/README.md b/app/templates/components/uk_components/skip-link/README.md
new file mode 100644
index 000000000..df5b1b119
--- /dev/null
+++ b/app/templates/components/uk_components/skip-link/README.md
@@ -0,0 +1,15 @@
+# Skip link
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+Find out when to use the skip link component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/skip-link).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/skip-link/#options-example-default) for details.
\ No newline at end of file
diff --git a/app/templates/components/uk_components/skip-link/_skip-link.scss b/app/templates/components/uk_components/skip-link/_skip-link.scss
new file mode 100644
index 000000000..ddccb1d2e
--- /dev/null
+++ b/app/templates/components/uk_components/skip-link/_skip-link.scss
@@ -0,0 +1,26 @@
+@import "../../settings/all";
+@import "../../tools/all";
+@import "../../helpers/all";
+
+@include govuk-exports("govuk/component/skip-link") {
+ .govuk-skip-link {
+ @include govuk-visually-hidden-focusable;
+ @include govuk-link-common;
+ @include govuk-link-style-text;
+ @include govuk-typography-responsive($size: 16);
+
+ display: block;
+ padding: govuk-spacing(2) govuk-spacing(3);
+
+ // Respect 'display cutout' safe area (avoids notches and rounded corners)
+ @supports (padding: unquote("max(calc(0px))")) {
+ $padding-safe-area-right: calc(#{govuk-spacing(3)} + env(safe-area-inset-right));
+ $padding-safe-area-left: calc(#{govuk-spacing(3)} + env(safe-area-inset-left));
+
+ // Use max() to pick largest padding, default or with safe area
+ // Escaped due to Sass max() vs. CSS native max()
+ padding-right: unquote("max(#{govuk-spacing(3)}, #{$padding-safe-area-right})");
+ padding-left: unquote("max(#{govuk-spacing(3)}, #{$padding-safe-area-left})");
+ }
+ }
+}
diff --git a/app/templates/components/uk_components/skip-link/macro-options.json b/app/templates/components/uk_components/skip-link/macro-options.json
new file mode 100644
index 000000000..619af1d5c
--- /dev/null
+++ b/app/templates/components/uk_components/skip-link/macro-options.json
@@ -0,0 +1,32 @@
+[
+ {
+ "name": "text",
+ "type": "string",
+ "required": true,
+ "description": "If `html` is set, this is not required. Text to use within the skip link component. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "html",
+ "type": "string",
+ "required": true,
+ "description": "If `text` is set, this is not required. HTML to use within the skip link component. If `html` is provided, the `text` argument will be ignored."
+ },
+ {
+ "name": "href",
+ "type": "string",
+ "required": true,
+ "description": "The value of the skip link href attribute. Defaults to"
+ },
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the skip link."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the skip link."
+ }
+]
\ No newline at end of file
diff --git a/app/templates/components/uk_components/skip-link/macro.njk b/app/templates/components/uk_components/skip-link/macro.njk
new file mode 100644
index 000000000..b5afb0c4e
--- /dev/null
+++ b/app/templates/components/uk_components/skip-link/macro.njk
@@ -0,0 +1,3 @@
+{% macro govukSkipLink(params) %}
+ {%- include "./template.njk" -%}
+{% endmacro %}
diff --git a/app/templates/components/uk_components/skip-link/template.njk b/app/templates/components/uk_components/skip-link/template.njk
new file mode 100644
index 000000000..b78695eae
--- /dev/null
+++ b/app/templates/components/uk_components/skip-link/template.njk
@@ -0,0 +1,3 @@
+
+ {{- params.html | safe if params.html else params.text -}}
+
diff --git a/app/templates/components/uk_components/textarea/README.md b/app/templates/components/uk_components/textarea/README.md
new file mode 100644
index 000000000..72abdfb8e
--- /dev/null
+++ b/app/templates/components/uk_components/textarea/README.md
@@ -0,0 +1,15 @@
+# Textarea
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+Find out when to use the textarea component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/textarea).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/textarea/#options-example-default) for details.
\ No newline at end of file
diff --git a/app/templates/components/uk_components/textarea/_textarea.scss b/app/templates/components/uk_components/textarea/_textarea.scss
new file mode 100644
index 000000000..d37145cc5
--- /dev/null
+++ b/app/templates/components/uk_components/textarea/_textarea.scss
@@ -0,0 +1,32 @@
+@import "../../settings/all";
+@import "../../tools/all";
+@import "../../helpers/all";
+
+@import "../error-message/error-message";
+@import "../hint/hint";
+@import "../label/label";
+
+@include govuk-exports("govuk/component/textarea") {
+ .govuk-textarea {
+ @include govuk-font($size: 19, $line-height: 1.25);
+ @include govuk-focusable;
+
+ box-sizing: border-box; // should this be global?
+ display: block;
+ width: 100%;
+ min-height: 40px;
+ @include govuk-responsive-margin(6, "bottom");
+ padding: govuk-spacing(1);
+
+ resize: vertical;
+
+ border: $govuk-border-width-form-element solid $govuk-input-border-colour;
+ border-radius: 0;
+
+ -webkit-appearance: none;
+ }
+
+ .govuk-textarea--error {
+ border: $govuk-border-width-form-element-error solid $govuk-error-colour;
+ }
+}
diff --git a/app/templates/components/uk_components/textarea/macro-options.json b/app/templates/components/uk_components/textarea/macro-options.json
new file mode 100644
index 000000000..ea2eefa9f
--- /dev/null
+++ b/app/templates/components/uk_components/textarea/macro-options.json
@@ -0,0 +1,85 @@
+[
+ {
+ "name": "id",
+ "type": "string",
+ "required": true,
+ "description": "The id of the textarea."
+ },
+ {
+ "name": "name",
+ "type": "string",
+ "required": true,
+ "description": "The name of the textarea, which is submitted with the form data."
+ },
+ {
+ "name": "rows",
+ "type": "string",
+ "required": false,
+ "description": "Optional number of textarea rows (default is 5 rows)."
+ },
+ {
+ "name": "value",
+ "type": "string",
+ "required": false,
+ "description": "Optional initial value of the textarea."
+ },
+ {
+ "name": "describedBy",
+ "type": "string",
+ "required": false,
+ "description": "One or more element IDs to add to the `aria-describedby` attribute, used to provide additional descriptive information for screenreader users."
+ },
+ {
+ "name": "label",
+ "type": "object",
+ "required": true,
+ "description": "Options for the label component.",
+ "isComponent": true
+ },
+ {
+ "name": "hint",
+ "type": "object",
+ "required": false,
+ "description": "Options for the hint component.",
+ "isComponent": true
+ },
+ {
+ "name": "errorMessage",
+ "type": "object",
+ "required": false,
+ "description": "Options for the errorMessage component (e.g. text).",
+ "isComponent": true
+ },
+ {
+ "name": "formGroup",
+ "type": "object",
+ "required": false,
+ "description": "Options for the form-group wrapper",
+ "params": [
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the form group (e.g. to show error state for the whole group)"
+ }
+ ]
+ },
+ {
+ "name": "classes",
+ "type": "string",
+ "required": false,
+ "description": "Classes to add to the textarea."
+ },
+ {
+ "name": "autocomplete",
+ "type": "string",
+ "required": false,
+ "description": "Attribute to [identify input purpose](https://www.w3.org/WAI/WCAG21/Understanding/identify-input-purpose.html), for instance \"postal-code\" or \"username\". See [autofill](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill) for full list of attributes that can be used."
+ },
+ {
+ "name": "attributes",
+ "type": "object",
+ "required": false,
+ "description": "HTML attributes (for example data attributes) to add to the textarea."
+ }
+]
\ No newline at end of file
diff --git a/app/templates/components/uk_components/textarea/macro.njk b/app/templates/components/uk_components/textarea/macro.njk
new file mode 100644
index 000000000..36a1c4ee7
--- /dev/null
+++ b/app/templates/components/uk_components/textarea/macro.njk
@@ -0,0 +1,3 @@
+{% macro govukTextarea(params) %}
+ {%- include "./template.njk" -%}
+{% endmacro %}
diff --git a/app/templates/components/uk_components/textarea/template.njk b/app/templates/components/uk_components/textarea/template.njk
new file mode 100644
index 000000000..56d9cc333
--- /dev/null
+++ b/app/templates/components/uk_components/textarea/template.njk
@@ -0,0 +1,44 @@
+{% from "../error-message/macro.njk" import govukErrorMessage -%}
+{% from "../hint/macro.njk" import govukHint %}
+{% from "../label/macro.njk" import govukLabel %}
+
+{#- a record of other elements that we need to associate with the input using
+ aria-describedby β for example hints or error messages -#}
+{% set describedBy = params.describedBy if params.describedBy else "" %}
+
diff --git a/app/templates/forms/fields/checkboxes/template.njk b/app/templates/forms/fields/checkboxes/template.njk
index f16afb376..10d1a7df8 100644
--- a/app/templates/forms/fields/checkboxes/template.njk
+++ b/app/templates/forms/fields/checkboxes/template.njk
@@ -1,7 +1,7 @@
-{% from "components/error-message/macro.njk" import govukErrorMessage -%}
-{% from "components/fieldset/macro.njk" import govukFieldset %}
-{% from "components/hint/macro.njk" import govukHint %}
-{% from "components/label/macro.njk" import govukLabel %}
+{% from "components/uk_components/error-message/macro.njk" import govukErrorMessage -%}
+{% from "components/uk_components/fieldset/macro.njk" import govukFieldset %}
+{% from "components/uk_components/hint/macro.njk" import govukHint %}
+{% from "components/uk_components/label/macro.njk" import govukLabel %}
{#- Copied from https://github.com/alphagov/govuk-frontend/blob/v2.13.0/src/components/checkboxes/template.njk
diff --git a/app/templates/main_template.html b/app/templates/main_template.html
index ca8ac9a8c..e6da3be7b 100644
--- a/app/templates/main_template.html
+++ b/app/templates/main_template.html
@@ -1,29 +1,26 @@
-{% from "./components/skip-link/macro.njk" import govukSkipLink -%}
-{# specify absolute url for the static assets folder e.g. http://wwww.domain.com/assets #}
-{%- set assetUrl = assetUrl | default(assetPath) -%}
- {% block pageTitle %}GOV.UK - The best place to find government services and information{% endblock %}
+ {% block pageTitle %}{% endblock %}
{# Hardcoded value of $govuk-black #}
{# Ensure that older IE versions always render with the correct rendering engine #}
{% block headIcons %}
-
- {# Hardcoded value of $govuk-black #}
-
-
-
-
+
+ {# Hardcoded value of $govuk-black #}
+
+
+
+
{% endblock %}
{% block head %}{% endblock %}
{# The default og:image is added below head so that scrapers see any custom metatags first, and this is just a fallback #}
{# image url needs to be absolute e.g. http://wwww.domain.com/.../govuk-opengraph-image.png #}
-
+
@@ -110,12 +107,7 @@
Sign in
-
{% endif %}
-
-
-
-