Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add beforeInput(s) and afterInput(s) options to form groups #4567

Merged
merged 4 commits into from
Feb 8, 2024

Conversation

colinrotherham
Copy link
Contributor

@colinrotherham colinrotherham commented Dec 14, 2023

This PR adds support for Nunjucks before/after content within components

It supports various improvements (see below) to new and existing patterns, for example:

  • Inserting a show/hide button after a password input
  • Inserting a credit card icon after a card number input

Nunjucks before/after content

Nunjucks before/after options have also been varied for components with single or multiple fields:

Components with single form field

Use options beforeInput and afterInput for components with a single field

govukInput({
  formGroup: {
    beforeInput: {
      html: "example HTML",
      text: "example text"
    },
    afterInput: {
      html: "example HTML",
      text: "example text"
    },
  }
})

Components with single form field

Use options beforeInputs and afterInputs for components with multiple fields

govukRadios({
  formGroup: {
    beforeInputs: {
      html: "example HTML",
      text: "example text"
    },
    afterInputs: {
      html: "example HTML",
      text: "example text"
    },
  }
})

☝️ Note that Password input will have an input + button combo, is the option name still suitable?

I picked "input" for all form controls (input, select, textarea) as we do with Error summary $input

All options considered might be:

  1. beforeInput/afterInput
  2. beforeControl/afterControl
  3. beforeField/afterField

Supporting other improvements

This work is based on a fix suggested by @36degrees in #1602 (comment) to solve these issues:

I don't think it'd have to be specific to hints though – we could allow e.g. an 'arbitrary' formGroup.beforeHtml / formGroup.afterHtml to be passed, which might also be useful for scenarios like those described in #924

It is a supporting change to enable "components within components" as used by:

Copy link

github-actions bot commented Dec 14, 2023

📋 Stats

File sizes

File Size
dist/govuk-frontend-development.min.css 112.45 KiB
dist/govuk-frontend-development.min.js 38.58 KiB
packages/govuk-frontend/dist/govuk/all.bundle.js 78.74 KiB
packages/govuk-frontend/dist/govuk/all.bundle.mjs 73.99 KiB
packages/govuk-frontend/dist/govuk/all.mjs 3.86 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend-component.mjs 359 B
packages/govuk-frontend/dist/govuk/govuk-frontend.min.css 112.44 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend.min.js 38.57 KiB
packages/govuk-frontend/dist/govuk/i18n.mjs 5.38 KiB

Modules

File Size
all.mjs 70.32 KiB
components/accordion/accordion.mjs 21.67 KiB
components/button/button.mjs 4.7 KiB
components/character-count/character-count.mjs 21.24 KiB
components/checkboxes/checkboxes.mjs 5.83 KiB
components/error-summary/error-summary.mjs 6.57 KiB
components/exit-this-page/exit-this-page.mjs 16.08 KiB
components/header/header.mjs 4.46 KiB
components/notification-banner/notification-banner.mjs 4.93 KiB
components/radios/radios.mjs 4.83 KiB
components/skip-link/skip-link.mjs 4.39 KiB
components/tabs/tabs.mjs 10.16 KiB

View stats and visualisations on the review app


Action run for 819324f

Copy link

github-actions bot commented Dec 14, 2023

Other changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/components/character-count/macro-options.json b/packages/govuk-frontend/dist/govuk/components/character-count/macro-options.json
index a740bfcee..6a1fec053 100644
--- a/packages/govuk-frontend/dist/govuk/components/character-count/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/character-count/macro-options.json
@@ -79,6 +79,46 @@
                 "type": "object",
                 "required": false,
                 "description": "HTML attributes (for example data attributes) to add to the form group."
+            },
+            {
+                "name": "beforeInput",
+                "type": "object",
+                "required": false,
+                "description": "Content to add before the textarea used by the character count component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add before the textarea. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add before the textarea. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
+            },
+            {
+                "name": "afterInput",
+                "type": "object",
+                "required": false,
+                "description": "Content to add after the textarea used by the character count component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add after the textarea. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add after the textarea. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
             }
         ]
     },
diff --git a/packages/govuk-frontend/dist/govuk/components/checkboxes/macro-options.json b/packages/govuk-frontend/dist/govuk/components/checkboxes/macro-options.json
index 8da436cb0..52020dc33 100644
--- a/packages/govuk-frontend/dist/govuk/components/checkboxes/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/checkboxes/macro-options.json
@@ -43,6 +43,46 @@
                 "type": "object",
                 "required": false,
                 "description": "HTML attributes (for example data attributes) to add to the form group."
+            },
+            {
+                "name": "beforeInputs",
+                "type": "object",
+                "required": false,
+                "description": "Content to add before all checkbox items within the checkboxes component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add before all checkbox items. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add before all checkbox items. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
+            },
+            {
+                "name": "afterInputs",
+                "type": "object",
+                "required": false,
+                "description": "Content to add after all checkbox items within the checkboxes component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add after all checkbox items. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add after all checkbox items. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
             }
         ]
     },
diff --git a/packages/govuk-frontend/dist/govuk/components/date-input/macro-options.json b/packages/govuk-frontend/dist/govuk/components/date-input/macro-options.json
index 8b6545b9a..afa2fc013 100644
--- a/packages/govuk-frontend/dist/govuk/components/date-input/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/date-input/macro-options.json
@@ -98,6 +98,46 @@
                 "type": "object",
                 "required": false,
                 "description": "HTML attributes (for example data attributes) to add to the form group."
+            },
+            {
+                "name": "beforeInputs",
+                "type": "object",
+                "required": false,
+                "description": "Content to add before the inputs used by the date input component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add before the inputs. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add before the inputs. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
+            },
+            {
+                "name": "afterInputs",
+                "type": "object",
+                "required": false,
+                "description": "Content to add after the inputs used by the date input component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add after the inputs. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add after the inputs. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
             }
         ]
     },
diff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/macro-options.json b/packages/govuk-frontend/dist/govuk/components/file-upload/macro-options.json
index 6e51af747..5db62cb10 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/macro-options.json
@@ -67,6 +67,46 @@
                 "type": "object",
                 "required": false,
                 "description": "HTML attributes (for example data attributes) to add to the form group."
+            },
+            {
+                "name": "beforeInput",
+                "type": "object",
+                "required": false,
+                "description": "Content to add before the input used by the file upload component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add before the input. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add before the input. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
+            },
+            {
+                "name": "afterInput",
+                "type": "object",
+                "required": false,
+                "description": "Content to add after the input used by the file upload component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add after the input. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add after the input. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
             }
         ]
     },
diff --git a/packages/govuk-frontend/dist/govuk/components/input/macro-options.json b/packages/govuk-frontend/dist/govuk/components/input/macro-options.json
index 018f8d1dc..1d7e6b2f1 100644
--- a/packages/govuk-frontend/dist/govuk/components/input/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/input/macro-options.json
@@ -130,7 +130,7 @@
         "name": "formGroup",
         "type": "object",
         "required": false,
-        "description": "Additional options for the form group containing the text-input component.",
+        "description": "Additional options for the form group containing the text input component.",
         "params": [
             {
                 "name": "classes",
@@ -143,6 +143,46 @@
                 "type": "object",
                 "required": false,
                 "description": "HTML attributes (for example data attributes) to add to the form group."
+            },
+            {
+                "name": "beforeInput",
+                "type": "object",
+                "required": false,
+                "description": "Content to add before the input used by the text input component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add before the input. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add before the input. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
+            },
+            {
+                "name": "afterInput",
+                "type": "object",
+                "required": false,
+                "description": "Content to add after the input used by the text input component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add after the input. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add after the input. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
             }
         ]
     },
diff --git a/packages/govuk-frontend/dist/govuk/components/radios/macro-options.json b/packages/govuk-frontend/dist/govuk/components/radios/macro-options.json
index 8af83b280..7c6cfe63e 100644
--- a/packages/govuk-frontend/dist/govuk/components/radios/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/radios/macro-options.json
@@ -37,6 +37,46 @@
                 "type": "object",
                 "required": false,
                 "description": "HTML attributes (for example data attributes) to add to the form group."
+            },
+            {
+                "name": "beforeInputs",
+                "type": "object",
+                "required": false,
+                "description": "Content to add before all radio items within the checkboxes component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add before all radio items. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add before all radio items. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
+            },
+            {
+                "name": "afterInputs",
+                "type": "object",
+                "required": false,
+                "description": "Content to add after all radio items within the checkboxes component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add after all radio items. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add after all radio items. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
             }
         ]
     },
@@ -50,7 +90,7 @@
         "name": "name",
         "type": "string",
         "required": true,
-        "description": "Name attribute for all radio items."
+        "description": "Name attribute for the radio items."
     },
     {
         "name": "items",
diff --git a/packages/govuk-frontend/dist/govuk/components/select/macro-options.json b/packages/govuk-frontend/dist/govuk/components/select/macro-options.json
index 838f05e26..0665b9479 100644
--- a/packages/govuk-frontend/dist/govuk/components/select/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/select/macro-options.json
@@ -105,6 +105,46 @@
                 "type": "object",
                 "required": false,
                 "description": "HTML attributes (for example data attributes) to add to the form group."
+            },
+            {
+                "name": "beforeInput",
+                "type": "object",
+                "required": false,
+                "description": "Content to add before the select used by the select component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add before the select. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add before the select. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
+            },
+            {
+                "name": "afterInput",
+                "type": "object",
+                "required": false,
+                "description": "Content to add after the select used by the select component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add after the select. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add after the select. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
             }
         ]
     },
diff --git a/packages/govuk-frontend/dist/govuk/components/textarea/macro-options.json b/packages/govuk-frontend/dist/govuk/components/textarea/macro-options.json
index 16249f7bb..cfe637803 100644
--- a/packages/govuk-frontend/dist/govuk/components/textarea/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/textarea/macro-options.json
@@ -79,6 +79,46 @@
                 "type": "object",
                 "required": false,
                 "description": "HTML attributes (for example data attributes) to add to the form group."
+            },
+            {
+                "name": "beforeInput",
+                "type": "object",
+                "required": false,
+                "description": "Content to add before the textarea used by the textarea component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add before the textarea. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add before the textarea. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
+            },
+            {
+                "name": "afterInput",
+                "type": "object",
+                "required": false,
+                "description": "Content to add after the textarea used by the textarea component.",
+                "params": [
+                    {
+                        "name": "text",
+                        "type": "string",
+                        "required": true,
+                        "description": "Text to add after the textarea. If `html` is provided, the `text` option will be ignored."
+                    },
+                    {
+                        "name": "html",
+                        "type": "string",
+                        "required": true,
+                        "description": "HTML to add after the textarea. If `html` is provided, the `text` option will be ignored."
+                    }
+                ]
             }
         ]
     },

Action run for 819324f

@querkmachine
Copy link
Member

Given recent discussions about the limitations of components that inherit other components (i.e. character count and EtP), I'm quite interested in this!

I'm less sure how much benefit there is to doing it this universally, though.

Being able to insert custom HTML after an input/before the form group closes seems like it will have some utility; but I can't really see much benefit in putting something at the start of the group before the label, hint and error message (or fieldset).

I don't think doing that's a behaviour we'd expect, and having it as an option doesn't seem like it'd help users do anything they can't usually already do by putting their custom HTML prior to the form group and potentially futzing with margins.

It feels like what we might actually want is the ability to inject HTML before and after the input element, rather than the form group as a whole. I'm not sure how well that might work in cases of radios or checkboxes, or text inputs using prefixes/suffixes, but it seems closer to what is desired in the linked issues.

@colinrotherham
Copy link
Contributor Author

That's great @querkmachine

To solve #1602 we only really need to add content after the <textarea>

So I'm open to narrowing it down and/or chuck me some ideas for renaming the options

@querkmachine
Copy link
Member

I agree that this could solve #1602, but I don't think it's necessarily a fix for #924, and I'm also not sure there are many situations outside of #1602 where having these parameters available would facilitate solving a problem.

For example, if I were wanting to add a icon before a text input, I wouldn't be able to do that here because beforeHtml comes before everything (label, hint and error message included) and afterHtml is after the input. The content order could be reversed with flexbox (although WCAG might preclude that), but the icon and input still wouldn't share a wrapper and we can't insert one ourselves with those parameters, making it similarly difficult.

This similarly wouldn't really help us solve other issues with nested components, like in the password input we're currently developing.

Code-wise I don't really see anything harmful with having the options, I just also don't see much use in them when compared to something akin to a beforeInput and afterInput—though I realise those may not work so well for controls like radios and checkboxes.

Would be interested in having this shopped around to other devs for their thoughts.

@colinrotherham
Copy link
Contributor Author

colinrotherham commented Jan 18, 2024

@querkmachine Using beforeInput and afterInput works for me, would that help?

Perhaps as an object with text and html keys as we'd typically do.

Your suggestion would work identically for Character count's <textarea>. For radios and checkboxes though we'd see those custom HTML slots move within the <fieldset> but that's alright?

@colinrotherham colinrotherham changed the title Add beforeHtml and afterHtml options to form groups Add beforeInput and afterInput options to form groups Feb 6, 2024
@colinrotherham colinrotherham changed the title Add beforeInput and afterInput options to form groups Add beforeInput(s) and afterInput(s) options to form groups Feb 7, 2024
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-4567 February 7, 2024 11:12 Inactive
Copy link
Member

@querkmachine querkmachine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all looking sensible to me. Should be a very useful thing to have!

@colinrotherham colinrotherham merged commit 78ca753 into main Feb 8, 2024
45 checks passed
@colinrotherham colinrotherham deleted the form-group-html branch February 8, 2024 09:04
@owenatgov owenatgov mentioned this pull request Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Development

Successfully merging this pull request may close these issues.

3 participants