-
Notifications
You must be signed in to change notification settings - Fork 10
[draft] Update to govuk frontend 5.7.1 #287
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
[draft] Update to govuk frontend 5.7.1 #287
Conversation
…utput raw HTML to disk for easier diffing (e.g. in IDE)
- banner role on header (no usages found, no change) - contentinfo role on footer (no usages found, no change) - main role on main (done, see "_Layout.cshtml") - navigation role on nav (done, see component "Pagination") - complementary role on aside (no usages found, no change) - region role on section (no usages found, no change) - article role on article (no usages found, no change) See also: alphagov/govuk-frontend#4854
…per govuk-frontend v5.4.0 alphagov/govuk-frontend#4971
…ontend v5.3.0 (fixing tag helper etc. is to follow) alphagov/govuk-frontend#4566
There are several minor changes in more recent versions, but the character component changes (introduced in v5.3.0) are proving to be a headache. Specifically, this seems to be the first case where the This, unfortunately, then seems to break many of the assumptions/logic in the helper methods/functionality which assumes they are at separate levels of nesting
Being mostly new to the internals, there is a decent chance I am missing something obvious however! 🥲
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of comments flagging thoughts / TODOs etc.
Apologies it's not all fully finished and polished!
<!-- <GovUkFrontendVersion>5.2.0</GovUkFrontendVersion>--> | ||
<!-- <GovUkFrontendVersion>5.3.0</GovUkFrontendVersion>--> | ||
<!-- <GovUkFrontendVersion>5.3.1</GovUkFrontendVersion>--> | ||
<!-- <GovUkFrontendVersion>5.4.0</GovUkFrontendVersion>--> | ||
<!-- <GovUkFrontendVersion>5.4.1</GovUkFrontendVersion>--> | ||
<!-- <GovUkFrontendVersion>5.5.0</GovUkFrontendVersion>--> | ||
<!-- <GovUkFrontendVersion>5.6.0</GovUkFrontendVersion>--> | ||
<!-- <GovUkFrontendVersion>5.7.0</GovUkFrontendVersion>--> | ||
<GovUkFrontendVersion>5.7.1</GovUkFrontendVersion> | ||
|
||
<_NpmLibDirectory>$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'lib'))</_NpmLibDirectory> | ||
<_NpmLibDirectory>$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'lib', 'govuk-frontend-$(GovUkFrontendVersion)'))</_NpmLibDirectory> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was doing a lot of jumping around versions to try and figure out when things broke and do incremental upgrades. This led to lots of delays each time the version changed (re-downloading it etc.)
This change caches the govuk-frontend
in versioned directories:
I'm explicitly flagging this as something I'm making use of currently on this branch, but it might not be desirable to merge in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this. We could probably do away with the version.txt
file with this change too.
tagBuilder.InnerHtml.AppendHtml(formGroup); | ||
tagBuilder.InnerHtml.AppendHtml(GenerateHint()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have separated responsibilities here, with GenerateCharacterCount
responsible for the outermost / root element only, and the content
(label, hint, error, textarea, remaining count message) being passed in/injected as an argument.
type: "text", | ||
item.Value, | ||
value: item.Value, | ||
describedBy: null, | ||
item.Autocomplete, | ||
item.Pattern, | ||
item.InputMode, | ||
autocomplete: item.Autocomplete, | ||
autocapitalize: null, | ||
pattern: item.Pattern, | ||
inputMode: item.InputMode, | ||
spellcheck: null, | ||
disabled, | ||
item.Attributes, | ||
disabled: disabled, | ||
attributes: item.Attributes, | ||
prefixContent: null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spurious IDE changes while experimenting.
TODO: Remove these.
/// <summary> | ||
/// The <c>autocapitalize</c> attribute for the generated <c>input</c> element. | ||
/// </summary> | ||
[HtmlAttributeName(AutocapitalizeAttributeName)] | ||
public string? Autocapitalize { get; set; } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've not done enough sleuthing to figure out when it got introduced, but autocapitalize
is included in the upstream tests and results in a conformance test failure:
Xunit.Sdk.XunitException
---
Actual:
---
<div class="govuk-form-group">
<label class="govuk-label" for="input-with-autocapitalize-off">
Autocapitalize is turned off
</label>
<input class="govuk-input" id="input-with-autocapitalize-off" name="autocapitalize" type="text">
</input>
</div>
---
Exected:
---
<div class="govuk-form-group">
<label class="govuk-label" for="input-with-autocapitalize-off">
Autocapitalize is turned off
</label>
<input class="govuk-input" id="input-with-autocapitalize-off" name="autocapitalize" type="text" autocapitalize="none">
</div>
---
AssertEx.HtmlEqual() Failure
* Missing Attribute
Path: div(0) > input(1)[autocapitalize]
Name: autocapitalize
Value: none
at GovUk.Frontend.AspNetCore.TestCommon.AssertEx.HtmlEqual(String expected, String actual, Predicate`1 excludeDiff, Boolean outputFullMarkupOnFailure) in C:\dev\govuk-frontend-aspnetcore\tests\GovUk.FrontEnd.AspNetCore.TestCommon\AssertEx.cs:line 81
at GovUk.Frontend.AspNetCore.ConformanceTests.ComponentTests.CheckComponentHtmlMatchesExpectedHtml[TOptions](ComponentTestCaseData`1 testCaseData, Func`3 generateComponent, Predicate`1 excludeDiff) in C:\dev\govuk-frontend-aspnetcore\tests\GovUk.Frontend.AspNetCore.ConformanceTests\ComponentTests.cs:line 49
at GovUk.Frontend.AspNetCore.ConformanceTests.ComponentTests.TextInput(ComponentTestCaseData`1 data) in C:\dev\govuk-frontend-aspnetcore\tests\GovUk.Frontend.AspNetCore.ConformanceTests\ComponentTests.TextInput.cs:line 17
throw new XunitException("---\nActual: \n---\n" + actual.Replace(">", ">\n").Replace("<", "\n<").Replace(">\n\n<", ">\n<").Trim() + "\n\n" + | ||
"---\nExected: \n---\n" + expected + "\n\n" + | ||
"---\n" + | ||
"" + sb.ToString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The HTML diff is very useful/required to flag where the differences are, but it only gets so far if not able to visualise the broader context i.e. the syntax tree / html string it is referring to (a-la "stop at the third red house on the left").
I have found it useful to be able to quickly reference expected/actual HTML, to then try and figure out whether it is the container versus a nested element (or both) whose behaviour is wrong.
It's a bit of a hacky solution and might not be desirable to merge this, however?
IHtmlContent GenerateCountRemainingMessage() | ||
{ | ||
// TODO / FIXME: temporary hardcoded, need to pass through from somewhere? Unable to access context from here? | ||
string textAreaDescriptionText = null; | ||
var hasNoLimit = MaxLength is null && MaxWords is null; // TODO: This logic is reused in many places -- centralise it? | ||
|
||
var hintId = $"{ResolveIdPrefix()}-info"; | ||
|
||
var content = hasNoLimit ? "" : | ||
(textAreaDescriptionText ?? $"You can enter up to %{{count}} {(MaxWords.HasValue ? "words" : "characters")}") | ||
.Replace("%{count}", (MaxWords.HasValue ? MaxWords : MaxLength).ToString()); | ||
|
||
var hintContent = new HtmlString(HtmlEncoder.Default.Encode(content)); | ||
|
||
var attributes = CountMessageAttributes.ToAttributeDictionary(); | ||
attributes.MergeCssClass("govuk-character-count__message"); | ||
|
||
return Generator.GenerateHint(hintId, hintContent, attributes); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flagging the to-do here. It's one of the examples where there seems to be a mismatch between data being stored on the *Context
but isn't available on the FormGroupTagHelperBase#GenerateFormGroupContent
method / overrides.
Note that tests aren't failing with this dodgy implementation, but maybe this means additional tests are needed?
{ | ||
// TODO / FIXME: temporary hardcoded, need to pass through from somewhere? Unable to access context from here? | ||
string textAreaDescriptionText = null; | ||
var hasNoLimit = MaxLength is null && MaxWords is null; // TODO: This logic is reused in many places -- centralise it? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming the *Context
could be made available, is it appropriate to centralise the hasNoLimit
logic to it? Somewhere else, perhaps?
<div class="govuk-width-container @ViewBag.ContainerClasses"> | ||
@RenderSection("BeforeContent", required: false) | ||
<main class="govuk-main-wrapper @ViewBag.MainClasses" id="main-content" role="main" lang="@ViewBag.MainLang"> | ||
<main class="govuk-main-wrapper @ViewBag.MainClasses" id="main-content" lang="@ViewBag.MainLang"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Assert | ||
var expectedHtml = @" | ||
<nav aria-label=""Pagination"" class=""govuk-pagination--block govuk-pagination"" role=""navigation""> | ||
<nav aria-label=""Pagination"" class=""govuk-pagination--block govuk-pagination""> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var actual = output.ToHtmlString(); | ||
var expectedHtml = @" | ||
<nav aria-label=""search"" class=""govuk-pagination"" role=""navigation""> | ||
<nav aria-label=""search"" class=""govuk-pagination""> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... At the time of creating the PR I had only two failing tests (one for an i8n data attribute on the character count component, and one on the text input component in the I clearly must have had something cached funny on my machine and doing a bunch of branch switching just now has unsettled things. It seems like there are quite a few additional conformance tests failing due to boolean conversions. It might just be an intermittent thing on my end (workflow is pending approval so can't yet tell from the PR checks) but I'll explore those tomorrow/another day. |
That's what's stopped me so far from making this upgrade. There's a sizeable refactor of this library going on (see the |
Thanks for PR @RogerHowellDfE. I think it would be good to upgrade to 5.3.0 first then upgrade to each frontend version separately, that way I can create a release for each version along the way. |
Reassuring to hear it's not a "just me" issue having difficulty with the implementation! 😓 😁
Apologies I missed the refactor happening on Is this something you might reasonably want some help with? I appreciate Some changes just need time to work through and adding extra people complicates things, so I promise to not be offended if you say no / not yet!
I'm happy to close this PR in favour of this plan. I've had my fun getting to know the library a bit better, so I'll not shed a tear at its loss. The changes are either trivial (no need to keep this PR for them), or relate to the character count component (not applicable once the refactor comes in?). Apologies for the unsolicited noise without discussing first! 😄 |
@RogerHowellDfE I'm grateful for the help and there are definitely some bits from this PR I'd like to steal :-) With hindsight having a completely separate branch that's been around for so long wasn't the right thing to do; I'm working on consolidating things now then changes should be easier to add on. I think an iterative approach to the changes I have planned is probably a better way than the big bang I was attempting previously. |
Intent
Currently this targets govuk-frontend v5.2.0 (released 21 Feb 2024).
This draft PR is work towards supporting govuk-frontend v5.7.1 (released 11 Oct 2024).
Out of scope of this PR are new tag helpers such as the password component (new in v5.3.0 #286 ). Ditto for older components such as the header (#18 ) or footer (#17 ) tag helpers.
Changes
role
attributes, per changes in govuk-frontend v5.3.0svg
crest logo (previouslypng
, per changes in v5.7.0These changes are also flagged as changes per test suites, but seemingly no explicit mention in the govuk-frontend changelog.
<ul>
, per conformance test expectationsautocapitalize
on text input components, per conformance test expectationswith customised input wrapper
caseNote: I did begin to do an incremental upgrade but all the headaches seem to be introduced in v5.3.0 (character count component) which makes this idea not so useful 🤷 .