diff --git a/app/main/forms.py b/app/main/forms.py
index a269bc385..81ba31ae0 100644
--- a/app/main/forms.py
+++ b/app/main/forms.py
@@ -655,7 +655,7 @@ class RegisterUserFromOrgInviteForm(StripWhitespaceForm):
auth_type = HiddenField("auth_type", validators=[DataRequired()])
-def govuk_checkbox_field_widget(self, field, param_extensions=None, **kwargs):
+def uswds_checkbox_field_widget(self, field, param_extensions=None, **kwargs):
# error messages
error_message = None
if field.errors:
@@ -695,7 +695,7 @@ def govuk_checkbox_field_widget(self, field, param_extensions=None, **kwargs):
) # nosec
-def govuk_checkboxes_field_widget(
+def uswds_checkboxes_field_widget(
self, field, wrap_in_collapsible=False, param_extensions=None, **kwargs
):
def _wrap_in_collapsible(field_label, checkboxes_string):
@@ -812,9 +812,9 @@ def govuk_radios_field_widget(self, field, param_extensions=None, **kwargs):
) # nosec
-class GovukCheckboxField(BooleanField):
+class USWDSCheckboxField(BooleanField):
def __init__(self, label="", validators=None, param_extensions=None, **kwargs):
- super(GovukCheckboxField, self).__init__(
+ super(USWDSCheckboxField, self).__init__(
label, validators, false_values=None, **kwargs
)
self.param_extensions = param_extensions
@@ -824,17 +824,17 @@ class GovukCheckboxField(BooleanField):
# 2. calls field.widget
# this bypasses that by making self.widget a method with the same interface as widget.__call__
def widget(self, field, param_extensions=None, **kwargs):
- return govuk_checkbox_field_widget(
+ return uswds_checkbox_field_widget(
self, field, param_extensions=param_extensions, **kwargs
)
# based on work done by @richardjpope: https://github.com/richardjpope/recourse/blob/master/recourse/forms.py#L6
-class GovukCheckboxesField(SelectMultipleField):
+class USWDSCheckboxesField(SelectMultipleField):
render_as_list = False
def __init__(self, label="", validators=None, param_extensions=None, **kwargs):
- super(GovukCheckboxesField, self).__init__(label, validators, **kwargs)
+ super(USWDSCheckboxesField, self).__init__(label, validators, **kwargs)
self.param_extensions = param_extensions
def get_item_from_option(self, option):
@@ -854,32 +854,32 @@ class GovukCheckboxesField(SelectMultipleField):
# 2. calls field.widget
# this bypasses that by making self.widget a method with the same interface as widget.__call__
def widget(self, field, param_extensions=None, **kwargs):
- return govuk_checkboxes_field_widget(
+ return uswds_checkboxes_field_widget(
self, field, param_extensions=param_extensions, **kwargs
)
# Wraps checkboxes rendering in HTML needed by the collapsible JS
-class GovukCollapsibleCheckboxesField(GovukCheckboxesField):
+class USWDSCollapsibleCheckboxesField(USWDSCheckboxesField):
def __init__(
self, label="", validators=None, field_label="", param_extensions=None, **kwargs
):
- super(GovukCollapsibleCheckboxesField, self).__init__(
+ super(USWDSCollapsibleCheckboxesField, self).__init__(
label, validators, param_extensions, **kwargs
)
self.field_label = field_label
def widget(self, field, **kwargs):
- return govuk_checkboxes_field_widget(
+ return uswds_checkboxes_field_widget(
self, field, wrap_in_collapsible=True, param_extensions=None, **kwargs
)
-# GovukCollapsibleCheckboxesField adds an ARIA live-region to the hint and wraps the render in HTML needed by the
+# USWDSCollapsibleCheckboxesField adds an ARIA live-region to the hint and wraps the render in HTML needed by the
# collapsible JS
# NestedFieldMixin puts the items into a tree hierarchy, pre-rendering the sub-trees of the top-level items
-class GovukCollapsibleNestedCheckboxesField(
- NestedFieldMixin, GovukCollapsibleCheckboxesField
+class USWDSCollapsibleNestedCheckboxesField(
+ NestedFieldMixin, USWDSCollapsibleCheckboxesField
):
NONE_OPTION_VALUE = None
render_as_list = True
@@ -998,7 +998,7 @@ class BasePermissionsForm(StripWhitespaceForm):
for item in ([{"name": "Templates", "id": None}] + all_template_folders)
]
- folder_permissions = GovukCollapsibleNestedCheckboxesField(
+ folder_permissions = USWDSCollapsibleNestedCheckboxesField(
"Folders this team member can see", field_label="folder"
)
@@ -1012,7 +1012,7 @@ class BasePermissionsForm(StripWhitespaceForm):
validators=[DataRequired()],
)
- permissions_field = GovukCheckboxesField(
+ permissions_field = USWDSCheckboxesField(
"Permissions",
filters=[filter_by_permissions],
choices=[(value, label) for value, label in permission_options],
@@ -1422,7 +1422,7 @@ class ServiceContactDetailsForm(StripWhitespaceForm):
class ServiceReplyToEmailForm(StripWhitespaceForm):
email_address = email_address(label="Reply-to email address", gov_user=False)
- is_default = GovukCheckboxField("Make this email address the default")
+ is_default = USWDSCheckboxField("Make this email address the default")
class ServiceSmsSenderForm(StripWhitespaceForm):
@@ -1436,11 +1436,11 @@ class ServiceSmsSenderForm(StripWhitespaceForm):
DoesNotStartWithDoubleZero(),
],
)
- is_default = GovukCheckboxField("Make this text message sender the default")
+ is_default = USWDSCheckboxField("Make this text message sender the default")
class ServiceEditInboundNumberForm(StripWhitespaceForm):
- is_default = GovukCheckboxField("Make this text message sender the default")
+ is_default = USWDSCheckboxField("Make this text message sender the default")
class AdminNotesForm(StripWhitespaceForm):
@@ -1528,7 +1528,7 @@ class GuestList(StripWhitespaceForm):
class DateFilterForm(StripWhitespaceForm):
start_date = GovukDateField("Start Date", [validators.optional()])
end_date = GovukDateField("End Date", [validators.optional()])
- include_from_test_key = GovukCheckboxField("Include test keys")
+ include_from_test_key = USWDSCheckboxField("Include test keys")
class RequiredDateFilterForm(StripWhitespaceForm):
@@ -1732,7 +1732,7 @@ class TemplateFolderForm(StripWhitespaceForm):
(item.id, item.name) for item in all_service_users
]
- users_with_permission = GovukCollapsibleCheckboxesField(
+ users_with_permission = USWDSCollapsibleCheckboxesField(
"Team members who can see this folder", field_label="team member"
)
name = GovukTextInputField(
@@ -1851,7 +1851,7 @@ class TemplateAndFoldersSelectionForm(Form):
return self.move_to_new_folder_name.data
return None
- templates_and_folders = GovukCheckboxesField(
+ templates_and_folders = USWDSCheckboxesField(
"Choose templates or folders",
validators=[required_for_ops("move-to-new-folder", "move-to-existing-folder")],
choices=[], # added to keep order of arguments, added properly in __init__
@@ -1883,7 +1883,7 @@ class TemplateAndFoldersSelectionForm(Form):
class AdminClearCacheForm(StripWhitespaceForm):
- model_type = GovukCheckboxesField(
+ model_type = USWDSCheckboxesField(
"What do you want to clear today",
)
diff --git a/app/templates/components/components/checkboxes/template.njk b/app/templates/components/components/checkboxes/template.njk
index 48a6b0b86..4932f3eb7 100644
--- a/app/templates/components/components/checkboxes/template.njk
+++ b/app/templates/components/components/checkboxes/template.njk
@@ -49,7 +49,7 @@
visuallyHiddenText: params.errorMessage.visuallyHiddenText
}) | indent(2) | trim }}
{% endif %}
-
{% for item in params.items %}
@@ -60,8 +60,8 @@
{% set itemHintId = id + "-item-hint" if hasHint else "" %}
{% set itemDescribedBy = describedBy if not hasFieldset else "" %}
{% set itemDescribedBy = (itemDescribedBy + " " + itemHintId) | trim %}
-
-
+
{% if item.conditional %}
-
+
{{ item.conditional.html | safe }}
{% endif %}
diff --git a/app/templates/forms/fields/checkboxes/template.njk b/app/templates/forms/fields/checkboxes/template.njk
index c1d006310..74d346346 100644
--- a/app/templates/forms/fields/checkboxes/template.njk
+++ b/app/templates/forms/fields/checkboxes/template.njk
@@ -1,16 +1,16 @@
{% from "components/components/error-message/macro.njk" import usaErrorMessage -%}
{% from "components/components/fieldset/macro.njk" import govukFieldset %}
{% from "components/components/hint/macro.njk" import usaHint %}
-{% from "components/components/radio-label/macro.njk" import usaRadioLabel %}
+{% from "components/components/label/macro.njk" import usaLabel %}
-{#- Copied from https://github.com/alphagov/govuk-frontend/blob/v2.13.0/src/components/checkboxes/template.njk
- Changes:
- - `formGroup` option to control whether or not the checkboxes are wrapped with a `usa-form-group` class
- - `classes` option added to `item` allow custom classes on the `.govuk-checkboxes__item` element
- - `classes` option added to `item.hint` allow custom classes on the `.usa-hint` element (added to GOVUK Frontend in v3.5.0 - remove when we update)
- - `asList` option added the root `params` object to allow setting of the `.govuk-checkboxes` and `.govuk-checkboxes__item` element types
- - `children` option added to `item` allowing the sending in of prerendered child checkboxes (allowing the creation of tree structures through recursion) -#}
+{#- Updated from GOV.UK components to USWDS patterns
+ Changed from original GOV.UK template:
+ - Uses USWDS checkbox classes (usa-checkbox, usa-checkbox__input, usa-checkbox__label)
+ - Conditional content uses display-none utility class instead of govuk-specific classes
+ - Label uses usaLabel macro instead of radio label
+ - Hint text uses usa-checkbox__label-description class
+ - Maintains all original functionality including conditional reveals and nested checkboxes -#}
{#- 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 %}
@@ -92,17 +92,17 @@
{%- if item.conditional %} data-aria-controls="{{ conditionalId }}"{% endif -%}
{%- if itemDescribedBy %} aria-describedby="{{ itemDescribedBy }}"{% endif -%}
{%- for attribute, value in item.attributes %} {{ attribute }}="{{ value }}"{% endfor -%}>
- {{ usaRadioLabel({
+ {{ usaLabel({
html: item.html,
text: item.text,
- classes: (' ' + item.label.classes if item.label.classes),
+ classes: 'usa-checkbox__label' + (' ' + item.label.classes if item.label.classes),
attributes: item.label.attributes,
for: id
}) | indent(6) | trim }}
{%- if hasHint %}
{{ usaHint({
id: itemHintId,
- classes: 'govuk-checkboxes__hint' + (' ' + item.hint.classes if item.hint.classes),
+ classes: 'usa-checkbox__label-description' + (' ' + item.hint.classes if item.hint.classes),
attributes: item.hint.attributes,
html: item.hint.html,
text: item.hint.text
@@ -112,14 +112,14 @@
{{ item.children | safe }}
{%- endif %}
{% if params.asList and item.conditional %}
-
+
{{ item.conditional.html | safe }}
{% endif %}
{%- if item.after %}{{ item.after }}{% endif -%}
{{ groupItemElement }}>
{% if not params.asList and item.conditional %}
-
+
{{ item.conditional.html | safe }}
{% endif %}
diff --git a/backstop_data/bitmaps_reference/backstop_test_About_0_document_0_desktop.png b/backstop_data/bitmaps_reference/backstop_test_About_0_document_0_desktop.png
index e823605be..9a985d5e1 100644
Binary files a/backstop_data/bitmaps_reference/backstop_test_About_0_document_0_desktop.png and b/backstop_data/bitmaps_reference/backstop_test_About_0_document_0_desktop.png differ
diff --git a/backstop_data/bitmaps_reference/backstop_test_Establish_Trust_0_document_0_desktop.png b/backstop_data/bitmaps_reference/backstop_test_Establish_Trust_0_document_0_desktop.png
index e3c06c069..6185e7efa 100644
Binary files a/backstop_data/bitmaps_reference/backstop_test_Establish_Trust_0_document_0_desktop.png and b/backstop_data/bitmaps_reference/backstop_test_Establish_Trust_0_document_0_desktop.png differ
diff --git a/backstop_data/bitmaps_reference/backstop_test_Invite_User_0_document_0_desktop.png b/backstop_data/bitmaps_reference/backstop_test_Invite_User_0_document_0_desktop.png
new file mode 100644
index 000000000..2c427b325
Binary files /dev/null and b/backstop_data/bitmaps_reference/backstop_test_Invite_User_0_document_0_desktop.png differ
diff --git a/backstop_data/bitmaps_reference/backstop_test_Platform_Admin_Live_Services_0_document_0_desktop.png b/backstop_data/bitmaps_reference/backstop_test_Platform_Admin_Live_Services_0_document_0_desktop.png
new file mode 100644
index 000000000..4de5b957e
Binary files /dev/null and b/backstop_data/bitmaps_reference/backstop_test_Platform_Admin_Live_Services_0_document_0_desktop.png differ
diff --git a/tests/app/main/views/organizations/test_organizations.py b/tests/app/main/views/organizations/test_organizations.py
index ceab59519..0e7c35e82 100644
--- a/tests/app/main/views/organizations/test_organizations.py
+++ b/tests/app/main/views/organizations/test_organizations.py
@@ -63,10 +63,7 @@ def test_organization_page_shows_all_organizations(
assert normalize_spaces(archived.text) == "- archived"
assert normalize_spaces(archived.parent.text) == "Test 2 - archived 2 live services"
- assert (
- normalize_spaces(page.select_one("a.usa-button").text)
- == "New organization"
- )
+ assert normalize_spaces(page.select_one("a.usa-button").text) == "New organization"
get_organizations.assert_called_once_with()
diff --git a/tests/javascripts/collapsibleCheckboxes.test.js b/tests/javascripts/collapsibleCheckboxes.test.js
index 9920f9b92..3d6c6bc1b 100644
--- a/tests/javascripts/collapsibleCheckboxes.test.js
+++ b/tests/javascripts/collapsibleCheckboxes.test.js
@@ -20,9 +20,9 @@ describe('Collapsible fieldset', () => {
for (let num = start; num <= end; num++) {
let id = `folder-permissions-${num}`;
- result += `