govuk_tech_docs 6.3.0 → 6.4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +15 -14
  3. data/.github/workflows/build-middleman-artifact.yaml +3 -3
  4. data/.github/workflows/check-documentation-updates.yaml +32 -0
  5. data/.github/workflows/check-gem-version.yaml +36 -0
  6. data/.github/workflows/npm-vulnerability-scanner.yaml +55 -0
  7. data/.github/workflows/pipeline.yaml +56 -0
  8. data/.github/workflows/publish-gem.yaml +70 -0
  9. data/.github/workflows/{deploy-to-pages.yaml → publish-github-pages.yaml} +4 -5
  10. data/.github/workflows/ruby-vulnerability-scanner.yaml +44 -0
  11. data/.github/workflows/test.yaml +9 -7
  12. data/.rspec +1 -0
  13. data/CHANGELOG.md +14 -0
  14. data/README.md +4 -1
  15. data/documentation/config/tech-docs.yml +1 -1
  16. data/documentation/source/configure_project/global_configuration/index.html.md.erb +9 -1
  17. data/lib/govuk_tech_docs/contribution_banner.rb +15 -3
  18. data/lib/govuk_tech_docs/version.rb +1 -1
  19. data/lib/source/layouts/_footer.erb +1 -1
  20. data/lib/source/layouts/_header.erb +1 -1
  21. data/lib/source/layouts/_service_navigation.erb +3 -1
  22. data/lib/source/layouts/core.erb +2 -4
  23. data/lib/tasks/lint.rake +87 -13
  24. data/node_modules/govuk-frontend/dist/govuk/all.bundle.js +2 -5
  25. data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs +2 -5
  26. data/node_modules/govuk-frontend/dist/govuk/common/govuk-frontend-version.mjs +1 -1
  27. data/node_modules/govuk-frontend/dist/govuk/components/_index.import.scss +3 -0
  28. data/node_modules/govuk-frontend/dist/govuk/components/_index.scss +3 -0
  29. data/node_modules/govuk-frontend/dist/govuk/components/breadcrumbs/_mixin.scss +1 -5
  30. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/_mixin.scss +7 -1
  31. data/node_modules/govuk-frontend/dist/govuk/components/cookie-banner/_mixin.scss +6 -0
  32. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/_mixin.scss +5 -1
  33. data/node_modules/govuk-frontend/dist/govuk/components/feedback/_feedback.import.scss +6 -0
  34. data/node_modules/govuk-frontend/dist/govuk/components/feedback/_index.import.scss +8 -0
  35. data/node_modules/govuk-frontend/dist/govuk/components/feedback/_index.scss +5 -0
  36. data/node_modules/govuk-frontend/dist/govuk/components/feedback/_mixin.scss +48 -0
  37. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js +1 -4
  38. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs +1 -4
  39. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs +1 -5
  40. data/node_modules/govuk-frontend/dist/govuk/components/footer/_mixin.scss +6 -0
  41. data/node_modules/govuk-frontend/dist/govuk/components/generic-header/_generic-header.import.scss +6 -0
  42. data/node_modules/govuk-frontend/dist/govuk/components/generic-header/_index.import.scss +8 -0
  43. data/node_modules/govuk-frontend/dist/govuk/components/generic-header/_index.scss +5 -0
  44. data/node_modules/govuk-frontend/dist/govuk/components/generic-header/_mixin.scss +140 -0
  45. data/node_modules/govuk-frontend/dist/govuk/components/header/_mixin.scss +9 -65
  46. data/node_modules/govuk-frontend/dist/govuk/components/input/_mixin.scss +1 -0
  47. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/_index.import.scss +8 -0
  48. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/_index.scss +6 -0
  49. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/_language-navigation.import.scss +6 -0
  50. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/_mixin.scss +68 -0
  51. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/_mixin.scss +8 -7
  52. data/node_modules/govuk-frontend/dist/govuk/components/panel/_mixin.scss +46 -12
  53. data/node_modules/govuk-frontend/dist/govuk/components/radios/_mixin.scss +7 -1
  54. data/node_modules/govuk-frontend/dist/govuk/components/select/_mixin.scss +0 -7
  55. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/_mixin.scss +55 -9
  56. data/node_modules/govuk-frontend/dist/govuk/custom-properties/_frontend-version.mixin.scss +1 -1
  57. data/node_modules/govuk-frontend/dist/govuk/custom-properties/_functional-colours.mixin.scss +1 -0
  58. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js +1 -1
  59. data/node_modules/govuk-frontend/dist/govuk/helpers/_links.scss +1 -1
  60. data/node_modules/govuk-frontend/dist/govuk/settings/_colours-functional.scss +3 -0
  61. data/node_modules/govuk-frontend/dist/govuk/settings/_colours-organisations.scss +16 -2
  62. data/node_modules/govuk-frontend/dist/govuk/tools/_exports.scss +1 -1
  63. data/package-lock.json +183 -582
  64. data/package.json +3 -3
  65. metadata +20 -4
  66. data/.github/workflows/dependency-review.yaml +0 -25
  67. data/.github/workflows/publish.yaml +0 -83
data/lib/tasks/lint.rake CHANGED
@@ -1,33 +1,107 @@
1
1
  # Rakefile
2
2
  require "json"
3
- require "open3"
3
+ require "timeout" # Built into standard Ruby
4
4
  require_relative "./helpers/rake_utils"
5
5
  require_relative "./helpers/vale_report"
6
6
 
7
7
  namespace :lint do
8
- # task vale_sync:
9
- desc "Run tech-docs-linter to check content against GOV.UK style guide."
8
+ desc "Run linter to check content against GOV.UK style guide."
10
9
  task :vale, [:target, :clean_build, :full_output] do |_t, args|
11
10
  args.with_defaults(target: "./build", clean_build: "true", full_output: "true")
12
11
 
13
- sh "bundle exec vale sync --config='#{vale_config_path}'"
12
+ Rake::Task["middleman:build"].invoke if args.clean_build == "true"
14
13
 
15
- if args.clean_build == "true"
16
- Rake::Task["middleman:build"].invoke
14
+ files = Dir.glob("#{args.target}/**/*.{html,md}")
15
+ puts "Running Vale against #{files.count} files...\n\n"
16
+
17
+ combined_json = {}
18
+
19
+ files.each do |file|
20
+ print "Linting #{file}... "
21
+
22
+ file_output = ""
23
+
24
+ # IO.popen runs the command and exposes the Process ID (PID)
25
+ IO.popen(["vale", "--config=#{vale_config_path}", "--output=JSON", file]) do |io|
26
+ begin
27
+ # If a file takes longer than 10 seconds, raise a timeout
28
+ Timeout.timeout(10) do
29
+ file_output = io.read
30
+ end
31
+ # If we reach here, it finished safely
32
+ puts "\e[32mDone\e[0m"
33
+ rescue Timeout::Error
34
+ # The regex hung. Send a SIGKILL to the Vale process to stop it chewing CPU
35
+ Process.kill("KILL", io.pid)
36
+ puts "\e[31mHUNG (Skipped due to timeout)\e[0m" # Red text
37
+ end
38
+ end
39
+
40
+ # Merge JSON only if we got a valid response (ignores timeouts)
41
+ unless file_output.strip.empty?
42
+ parsed_output = JSON.parse(file_output)
43
+ combined_json.merge!(parsed_output) unless parsed_output.empty?
44
+ end
17
45
  end
18
46
 
19
- stdout, = Open3.capture3("vale --config='#{vale_config_path}' --output=JSON #{args.target}")
47
+ puts "\nGenerating report..."
20
48
 
21
- linter_report = ValeLinterReport.new(stdout)
49
+ linter_report = ValeLinterReport.new(combined_json.to_json)
22
50
  linter_report.format_linter_output
23
- if args.full_output == "true"
24
- puts linter_report.get_linter_full_report
25
- end
51
+
52
+ puts linter_report.get_linter_full_report if args.full_output == "true"
26
53
  puts linter_report.get_linter_summary_report
27
54
 
28
- # finish with a Ci friendly json string
29
55
  linter_report.linter_summary_report_json
30
- # Always exit 0 so individual project pipelines can evaluate the data themselves
31
56
  exit 0
32
57
  end
58
+
59
+ desc "Debug Vale to find which rule hangs on a specific file."
60
+ require 'timeout'
61
+
62
+ desc "Debug specific Vale rules for regex hangs"
63
+ task :debug, [:rules] do |_, args|
64
+ # Accepts Rake args (rake "debug[Rule1,Rule2]") or ENV vars (rake debug RULES=Rule1,Rule2)
65
+ raw_input = args[:rules] || ENV['RULES']
66
+
67
+ if raw_input.nil? || raw_input.strip.empty?
68
+ abort "Please provide rules to test. \nUsage: rake \"debug[Rule1,Rule2]\" OR rake debug RULES=Rule1,Rule2"
69
+ end
70
+
71
+ # Split by comma, remove whitespace, and drop any empty strings
72
+ rules = raw_input.split(',').map(&:strip).reject(&:empty?)
73
+
74
+ style_prefix = 'style-guide'
75
+ target_file = './build/search/index.html'
76
+
77
+ puts "Hunting for the hanging regex in #{target_file}..."
78
+ puts "Testing #{rules.size} rule(s): #{rules.join(', ')}\n\n"
79
+
80
+ rules.each do |rule_name|
81
+ full_rule = "#{style_prefix}.#{rule_name}"
82
+ print "Testing #{full_rule}... "
83
+ filter_string = ".Name=='#{full_rule}'"
84
+
85
+ # Run Vale for just this single rule
86
+ IO.popen(["vale", "--filter=#{filter_string}", "--output=line", target_file]) do |io|
87
+ begin
88
+ # If the regex loops catastrophically, it hits this 5-second limit
89
+ Timeout.timeout(5) do
90
+ io.read
91
+ end
92
+
93
+ # If it finishes within 5 seconds, the rule is safe
94
+ puts "\e[32mPassed (No hang)\e[0m"
95
+
96
+ rescue Timeout::Error
97
+ # The regex froze! Kill the underlying process to save CPU and flag it
98
+ Process.kill("KILL", io.pid)
99
+ puts "\e[31m💥 HUNG! (This is the broken regex)\e[0m"
100
+ end
101
+ end
102
+ end
103
+
104
+ exit 0
105
+ end
106
+
33
107
  end
@@ -4,7 +4,7 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.GOVUKFrontend = global.GOVUKFrontend || {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
- const version = '6.2.0';
7
+ const version = '6.5.1';
8
8
 
9
9
  function getBreakpoint(name) {
10
10
  const property = `--govuk-breakpoint-${name}`;
@@ -1594,16 +1594,13 @@
1594
1594
  this.id = void 0;
1595
1595
  this.$announcements = void 0;
1596
1596
  this.enteredAnotherElement = void 0;
1597
- const $input = this.$root.querySelector('input');
1597
+ const $input = this.$root.querySelector('input[type="file"]');
1598
1598
  if ($input === null) {
1599
1599
  throw new ElementError({
1600
1600
  component: FileUpload,
1601
1601
  identifier: 'File inputs (`<input type="file">`)'
1602
1602
  });
1603
1603
  }
1604
- if ($input.type !== 'file') {
1605
- throw new ElementError(formatErrorMessage(FileUpload, 'File input (`<input type="file">`) attribute (`type`) is not `file`'));
1606
- }
1607
1604
  this.$input = $input;
1608
1605
  if (!this.$input.id) {
1609
1606
  throw new ElementError({
@@ -1,4 +1,4 @@
1
- const version = '6.2.0';
1
+ const version = '6.5.1';
2
2
 
3
3
  function getBreakpoint(name) {
4
4
  const property = `--govuk-breakpoint-${name}`;
@@ -1588,16 +1588,13 @@ class FileUpload extends ConfigurableComponent {
1588
1588
  this.id = void 0;
1589
1589
  this.$announcements = void 0;
1590
1590
  this.enteredAnotherElement = void 0;
1591
- const $input = this.$root.querySelector('input');
1591
+ const $input = this.$root.querySelector('input[type="file"]');
1592
1592
  if ($input === null) {
1593
1593
  throw new ElementError({
1594
1594
  component: FileUpload,
1595
1595
  identifier: 'File inputs (`<input type="file">`)'
1596
1596
  });
1597
1597
  }
1598
- if ($input.type !== 'file') {
1599
- throw new ElementError(formatErrorMessage(FileUpload, 'File input (`<input type="file">`) attribute (`type`) is not `file`'));
1600
- }
1601
1598
  this.$input = $input;
1602
1599
  if (!this.$input.id) {
1603
1600
  throw new ElementError({
@@ -1,4 +1,4 @@
1
- const version = '6.2.0';
1
+ const version = '6.5.1';
2
2
 
3
3
  export { version };
4
4
  //# sourceMappingURL=govuk-frontend-version.mjs.map
@@ -10,14 +10,17 @@
10
10
  @import "error-message";
11
11
  @import "error-summary";
12
12
  @import "exit-this-page";
13
+ @import "feedback";
13
14
  @import "fieldset";
14
15
  @import "file-upload";
15
16
  @import "footer";
17
+ @import "generic-header";
16
18
  @import "header";
17
19
  @import "hint";
18
20
  @import "input";
19
21
  @import "inset-text";
20
22
  @import "label";
23
+ @import "language-navigation";
21
24
  @import "notification-banner";
22
25
  @import "pagination";
23
26
  @import "panel";
@@ -10,14 +10,17 @@
10
10
  @use "error-message";
11
11
  @use "error-summary";
12
12
  @use "exit-this-page";
13
+ @use "feedback";
13
14
  @use "fieldset";
14
15
  @use "file-upload";
15
16
  @use "footer";
17
+ @use "generic-header";
16
18
  @use "header";
17
19
  @use "hint";
18
20
  @use "input";
19
21
  @use "inset-text";
20
22
  @use "label";
23
+ @use "language-navigation";
21
24
  @use "notification-banner";
22
25
  @use "pagination";
23
26
  @use "panel";
@@ -124,11 +124,7 @@
124
124
  }
125
125
 
126
126
  .govuk-breadcrumbs--inverse {
127
- color: base.govuk-colour("white");
128
-
129
- .govuk-breadcrumbs__link {
130
- @include base.govuk-link-style-inverse;
131
- }
127
+ --govuk-text-colour: #{base.govuk-functional-colour(inverse-text)};
132
128
 
133
129
  .govuk-breadcrumbs__list-item::before {
134
130
  border-color: currentcolor;
@@ -41,7 +41,7 @@
41
41
  // __item using flex-wrap because we want hints on a separate line.
42
42
  max-width: calc(100% - #{(($govuk-checkboxes-label-padding-left-right * 2) + $govuk-touch-target-size)});
43
43
  margin-bottom: 0;
44
- padding: (base.govuk-spacing(1) + base.$govuk-border-width-form-element) base.govuk-spacing(3);
44
+ padding: (base.govuk-spacing(1) + base.$govuk-border-width-form-element) $govuk-checkboxes-label-padding-left-right;
45
45
  cursor: pointer;
46
46
  // remove 300ms pause on mobile
47
47
  touch-action: manipulation;
@@ -206,6 +206,12 @@
206
206
  }
207
207
 
208
208
  .govuk-checkboxes__label {
209
+ // Recalculate max-width to account for the smaller checkbox size
210
+ // 1px comes from padding-left (defined below)
211
+ max-width: calc(
212
+ 100% - #{($govuk-touch-target-size - $input-offset) + $govuk-checkboxes-label-padding-left-right + 1px}
213
+ );
214
+
209
215
  // Create a tiny space between the small checkbox hover state so that it
210
216
  // doesn't clash with the label
211
217
  padding-left: 1px;
@@ -16,6 +16,12 @@
16
16
 
17
17
  color: base.govuk-functional-colour(surface-text);
18
18
  background-color: base.govuk-functional-colour(surface-background);
19
+
20
+ @media print {
21
+ border-bottom-color: currentcolor;
22
+ color: base.govuk-functional-colour(print-text);
23
+ background-color: transparent;
24
+ }
19
25
  }
20
26
 
21
27
  // Support older browsers which don't hide elements with the `hidden` attribute
@@ -69,7 +69,11 @@
69
69
  right: 0;
70
70
  bottom: 0;
71
71
  left: 0;
72
- background-color: base.govuk-colour("white");
72
+ // The overlay is imitating a default browser window so we can use
73
+ // system colours ensure it matches the browser's default colours.
74
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/system-color
75
+ color: CanvasText;
76
+ background-color: Canvas;
73
77
  }
74
78
 
75
79
  // This class is added to the body when the Exit This Page button is activated
@@ -0,0 +1,6 @@
1
+ @use "../../settings/warnings--internal";
2
+
3
+ @include warnings--internal.component-scss-file-warning("feedback");
4
+
5
+ @import "index";
6
+
@@ -0,0 +1,8 @@
1
+ @use "mixin";
2
+
3
+ @import "../../base";
4
+
5
+ @include govuk-exports("govuk/component/feedback") {
6
+ @include mixin.styles;
7
+ }
8
+
@@ -0,0 +1,5 @@
1
+ @use "../../custom-properties";
2
+ @use "mixin";
3
+
4
+ @include mixin.styles;
5
+
@@ -0,0 +1,48 @@
1
+ @use "../../base";
2
+
3
+ /// @access private
4
+ @mixin styles {
5
+ .govuk-feedback {
6
+ box-sizing: border-box;
7
+ // Tie left/right padding to page gutter as it stretches across the whole
8
+ // screen on smaller screens
9
+ padding: base.govuk-spacing(4) base.$govuk-gutter-half base.govuk-spacing(5);
10
+ border-top: 1px solid;
11
+ border-color: base.govuk-functional-colour("brand");
12
+ background-color: base.govuk-functional-colour("surface-background");
13
+
14
+ @media #{base.govuk-from-breakpoint(tablet)} {
15
+ padding-right: base.govuk-spacing(4);
16
+ padding-left: base.govuk-spacing(4);
17
+ }
18
+
19
+ // Override $govuk-width-container's left and right margin as we want Feedback
20
+ // to go across the whole screen on smaller screens
21
+ @media #{base.govuk-until-breakpoint(tablet)} {
22
+ margin-right: 0;
23
+ margin-left: 0;
24
+ }
25
+
26
+ @media print {
27
+ border-color: currentcolor;
28
+ background-color: transparent;
29
+ }
30
+ }
31
+
32
+ .govuk-feedback__title {
33
+ @include base.govuk-font($size: 24, $weight: bold);
34
+ margin-top: 0;
35
+ color: base.govuk-functional-colour(text);
36
+ @include base.govuk-responsive-margin(1, "bottom");
37
+ }
38
+
39
+ // Removes the bottom margin from the final child element eg: a paragraph
40
+ //
41
+ // Feedback body doesn't have any opinions about typography. Instead we defer
42
+ // to users to use typography classes in their input, or apply a `govuk-body`
43
+ // paragraph for if users pass `text`.
44
+ .govuk-feedback__body > :last-child {
45
+ margin-bottom: 0;
46
+ }
47
+ }
48
+
@@ -387,16 +387,13 @@
387
387
  this.id = void 0;
388
388
  this.$announcements = void 0;
389
389
  this.enteredAnotherElement = void 0;
390
- const $input = this.$root.querySelector('input');
390
+ const $input = this.$root.querySelector('input[type="file"]');
391
391
  if ($input === null) {
392
392
  throw new ElementError({
393
393
  component: FileUpload,
394
394
  identifier: 'File inputs (`<input type="file">`)'
395
395
  });
396
396
  }
397
- if ($input.type !== 'file') {
398
- throw new ElementError(formatErrorMessage(FileUpload, 'File input (`<input type="file">`) attribute (`type`) is not `file`'));
399
- }
400
397
  this.$input = $input;
401
398
  if (!this.$input.id) {
402
399
  throw new ElementError({
@@ -381,16 +381,13 @@ class FileUpload extends ConfigurableComponent {
381
381
  this.id = void 0;
382
382
  this.$announcements = void 0;
383
383
  this.enteredAnotherElement = void 0;
384
- const $input = this.$root.querySelector('input');
384
+ const $input = this.$root.querySelector('input[type="file"]');
385
385
  if ($input === null) {
386
386
  throw new ElementError({
387
387
  component: FileUpload,
388
388
  identifier: 'File inputs (`<input type="file">`)'
389
389
  });
390
390
  }
391
- if ($input.type !== 'file') {
392
- throw new ElementError(formatErrorMessage(FileUpload, 'File input (`<input type="file">`) attribute (`type`) is not `file`'));
393
- }
394
391
  this.$input = $input;
395
392
  if (!this.$input.id) {
396
393
  throw new ElementError({
@@ -1,6 +1,5 @@
1
1
  import { closestAttributeValue } from '../../common/closest-attribute-value.mjs';
2
2
  import { ConfigurableComponent } from '../../common/configuration.mjs';
3
- import { formatErrorMessage } from '../../common/index.mjs';
4
3
  import { ElementError } from '../../errors/index.mjs';
5
4
  import { I18n } from '../../i18n.mjs';
6
5
 
@@ -25,16 +24,13 @@ class FileUpload extends ConfigurableComponent {
25
24
  this.id = void 0;
26
25
  this.$announcements = void 0;
27
26
  this.enteredAnotherElement = void 0;
28
- const $input = this.$root.querySelector('input');
27
+ const $input = this.$root.querySelector('input[type="file"]');
29
28
  if ($input === null) {
30
29
  throw new ElementError({
31
30
  component: FileUpload,
32
31
  identifier: 'File inputs (`<input type="file">`)'
33
32
  });
34
33
  }
35
- if ($input.type !== 'file') {
36
- throw new ElementError(formatErrorMessage(FileUpload, 'File input (`<input type="file">`) attribute (`type`) is not `file`'));
37
- }
38
34
  this.$input = $input;
39
35
  if (!this.$input.id) {
40
36
  throw new ElementError({
@@ -19,6 +19,12 @@
19
19
  border-top-color: base.govuk-functional-colour(brand);
20
20
  color: $govuk-footer-text;
21
21
  background: base.govuk-functional-colour(template-background);
22
+
23
+ @media print {
24
+ border-top-color: currentcolor;
25
+ color: base.govuk-functional-colour(text);
26
+ background-color: transparent;
27
+ }
22
28
  }
23
29
 
24
30
  .govuk-footer__crown {
@@ -0,0 +1,6 @@
1
+ @use "../../settings/warnings--internal";
2
+
3
+ @include warnings--internal.component-scss-file-warning("generic-header");
4
+
5
+ @import "index";
6
+
@@ -0,0 +1,8 @@
1
+ @use "mixin";
2
+
3
+ @import "../../base";
4
+
5
+ @include govuk-exports("govuk/component/generic-header") {
6
+ @include mixin.styles;
7
+ }
8
+
@@ -0,0 +1,5 @@
1
+ @use "../../custom-properties";
2
+ @use "mixin";
3
+
4
+ @include mixin.styles;
5
+
@@ -0,0 +1,140 @@
1
+ ////
2
+ /// @group components/generic-header
3
+ ////
4
+
5
+ @use "../../base";
6
+
7
+ /// Width of transparent bottom border of header.
8
+ /// Set to provide a visual border in forced colour modes
9
+ ///
10
+ /// @type Number
11
+ /// @access private
12
+ $header-forced-colour-border-width: 1px;
13
+
14
+ /// Shared block header styles, with automatic background setting
15
+ ///
16
+ /// @param {String} $background-colour - background colour of the header
17
+ /// @param {String} $text-colour - text colour of the header
18
+ /// @access private
19
+ @mixin block-styles($background-colour: base.govuk-colour("black"), $text-colour: base.govuk-colour("white")) {
20
+ @include base.govuk-font($size: 16, $line-height: 1);
21
+
22
+ // Add a transparent bottom border for forced-colour modes
23
+ border-bottom: $header-forced-colour-border-width solid transparent;
24
+
25
+ --govuk-text-colour: #{$text-colour};
26
+ color: base.govuk-functional-colour(text);
27
+ background: $background-colour;
28
+
29
+ @media print {
30
+ border-bottom-width: 0;
31
+
32
+ --govuk-text-colour: inherit;
33
+ background: transparent;
34
+ }
35
+ }
36
+
37
+ /// Shared header full width container styles
38
+ ///
39
+ /// @access private
40
+ @mixin full-width-container-styles() {
41
+ padding: 0 base.$govuk-gutter-half;
42
+ }
43
+
44
+ /// Shared header logo container element styles, with automating padding setting
45
+ ///
46
+ /// @param {String} $padding-top - top padding of logo container
47
+ /// @param {String} $padding-bottom - bottom padding of logo container
48
+ /// @access private
49
+ @mixin logo-styles(
50
+ $padding-top: (
51
+ base.govuk-spacing(3)
52
+ ),
53
+ $padding-bottom: (
54
+ base.govuk-spacing(3)
55
+ )
56
+ ) {
57
+ padding-top: $padding-top;
58
+ padding-bottom: $padding-bottom;
59
+ }
60
+
61
+ /// Shared header logo link element styles
62
+ ///
63
+ /// @access private
64
+ @mixin link-styles {
65
+ // Avoid using the `base.govuk-link-common` mixin because the links in the
66
+ // header get a special treatment, because:
67
+ //
68
+ // - underlines are only visible on hover
69
+ // - all links get a 3px underline regardless of text size, as there are
70
+ // multiple grouped elements close to one another and having slightly
71
+ // different underline widths looks unbalanced
72
+ //
73
+ // Font size needs to be set on the link so that the box sizing is correct
74
+ // in Firefox
75
+ display: inline;
76
+ margin-right: base.govuk-spacing(2);
77
+ font-size: 30px; // We don't have a mixin that produces 30px font size
78
+ text-decoration: none;
79
+
80
+ @include base.govuk-link-style-text;
81
+
82
+ &:link,
83
+ &:visited {
84
+ text-decoration: none;
85
+ }
86
+
87
+ &:hover,
88
+ &:active {
89
+ // Negate the added border
90
+ $link-underline-thickness: 3px;
91
+ margin-bottom: $link-underline-thickness * -1;
92
+ border-bottom: $link-underline-thickness solid;
93
+ }
94
+
95
+ &:focus {
96
+ // Remove any borders that show when focused and hovered.
97
+ margin-bottom: 0;
98
+ border-bottom: 0;
99
+
100
+ @include base.govuk-focused-text;
101
+ }
102
+
103
+ @media print {
104
+ &:link,
105
+ &:visited {
106
+ color: base.govuk-functional-colour(text);
107
+ }
108
+
109
+ // Do not append link href to GOV.UK link when printing (e.g. '(/)')
110
+ &::after {
111
+ content: "";
112
+ }
113
+ }
114
+ }
115
+
116
+ /// @access private
117
+ @mixin styles {
118
+ .govuk-generic-header {
119
+ @include block-styles;
120
+ }
121
+
122
+ .govuk-generic-header__container--full-width {
123
+ @include full-width-container-styles;
124
+ }
125
+
126
+ .govuk-generic-header__logo {
127
+ @include logo-styles;
128
+ }
129
+
130
+ .govuk-generic-header__homepage-link {
131
+ @include link-styles;
132
+
133
+ // Automatically centre align direct child elements to help users with
134
+ // positioning their logo assets eg: as `svg`s or `img`s
135
+ > * {
136
+ vertical-align: top;
137
+ }
138
+ }
139
+ }
140
+