govuk_publishing_components 29.7.0 → 29.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/govuk_publishing_components/analytics/explicit-cross-domain-links.js +72 -73
- data/app/assets/javascripts/govuk_publishing_components/analytics/page-content.js +13 -2
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/gtm-click-tracking.js +49 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4.js +1 -0
- data/app/assets/javascripts/govuk_publishing_components/components/accordion.js +0 -1
- data/app/assets/javascripts/govuk_publishing_components/modules.js +0 -1
- data/app/assets/javascripts/govuk_publishing_components/vendor/lux/lux-measurer.js +37 -0
- data/app/assets/javascripts/govuk_publishing_components/vendor/lux/lux-reporter.js +166 -142
- data/app/assets/stylesheets/govuk_publishing_components/components/_cards.scss +11 -4
- data/app/assets/stylesheets/govuk_publishing_components/components/_contextual-sidebar.scss +20 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +3 -8
- data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_attachment.scss +8 -2
- data/app/controllers/govuk_publishing_components/audit_controller.rb +3 -2
- data/app/controllers/govuk_publishing_components/component_guide_controller.rb +0 -9
- data/app/models/govuk_publishing_components/audit_comparer.rb +92 -34
- data/app/views/govuk_publishing_components/audit/_applications.html.erb +20 -9
- data/app/views/govuk_publishing_components/component_guide/index.html.erb +3 -21
- data/app/views/govuk_publishing_components/component_guide/show.html.erb +1 -1
- data/app/views/govuk_publishing_components/components/_cards.html.erb +13 -11
- data/app/views/govuk_publishing_components/components/_layout_footer.html.erb +20 -2
- data/app/views/govuk_publishing_components/components/_summary_list.html.erb +4 -5
- data/app/views/govuk_publishing_components/components/contextual_sidebar/_ukraine_cta.html.erb +18 -19
- data/app/views/govuk_publishing_components/components/docs/contents_list.yml +1 -1
- data/app/views/govuk_publishing_components/components/docs/document_list.yml +4 -4
- data/app/views/govuk_publishing_components/components/docs/heading.yml +1 -1
- data/app/views/govuk_publishing_components/components/docs/image_card.yml +1 -1
- data/app/views/govuk_publishing_components/components/docs/meta_tags.yml +4 -4
- data/app/views/govuk_publishing_components/components/docs/metadata.yml +1 -1
- data/app/views/govuk_publishing_components/components/docs/share_links.yml +1 -1
- data/app/views/govuk_publishing_components/components/docs/subscription_links.yml +1 -1
- data/app/views/govuk_publishing_components/components/docs/translation_nav.yml +1 -2
- data/config/locales/ar.yml +1 -2
- data/config/locales/az.yml +1 -2
- data/config/locales/be.yml +1 -2
- data/config/locales/bg.yml +1 -2
- data/config/locales/bn.yml +1 -2
- data/config/locales/cs.yml +1 -2
- data/config/locales/cy.yml +1 -2
- data/config/locales/da.yml +1 -2
- data/config/locales/de.yml +1 -2
- data/config/locales/dr.yml +1 -2
- data/config/locales/el.yml +1 -2
- data/config/locales/en.yml +9 -2
- data/config/locales/es-419.yml +1 -2
- data/config/locales/es.yml +1 -2
- data/config/locales/et.yml +1 -2
- data/config/locales/fa.yml +1 -2
- data/config/locales/fi.yml +1 -2
- data/config/locales/fr.yml +1 -2
- data/config/locales/gd.yml +1 -2
- data/config/locales/gu.yml +1 -2
- data/config/locales/he.yml +1 -2
- data/config/locales/hi.yml +1 -2
- data/config/locales/hr.yml +1 -2
- data/config/locales/hu.yml +1 -2
- data/config/locales/hy.yml +1 -2
- data/config/locales/id.yml +1 -2
- data/config/locales/is.yml +1 -2
- data/config/locales/it.yml +1 -2
- data/config/locales/ja.yml +1 -2
- data/config/locales/ka.yml +1 -2
- data/config/locales/kk.yml +1 -2
- data/config/locales/ko.yml +1 -2
- data/config/locales/lt.yml +1 -2
- data/config/locales/lv.yml +1 -2
- data/config/locales/ms.yml +1 -2
- data/config/locales/mt.yml +1 -2
- data/config/locales/nl.yml +1 -2
- data/config/locales/no.yml +1 -2
- data/config/locales/pa-pk.yml +1 -2
- data/config/locales/pa.yml +1 -2
- data/config/locales/pl.yml +1 -2
- data/config/locales/ps.yml +1 -2
- data/config/locales/pt.yml +1 -2
- data/config/locales/ro.yml +1 -2
- data/config/locales/ru.yml +1 -2
- data/config/locales/si.yml +1 -2
- data/config/locales/sk.yml +1 -2
- data/config/locales/sl.yml +1 -2
- data/config/locales/so.yml +1 -2
- data/config/locales/sq.yml +1 -2
- data/config/locales/sr.yml +1 -2
- data/config/locales/sv.yml +1 -2
- data/config/locales/sw.yml +1 -2
- data/config/locales/ta.yml +1 -2
- data/config/locales/th.yml +1 -2
- data/config/locales/tk.yml +1 -2
- data/config/locales/tr.yml +1 -2
- data/config/locales/uk.yml +1 -2
- data/config/locales/ur.yml +1 -2
- data/config/locales/uz.yml +1 -2
- data/config/locales/vi.yml +1 -2
- data/config/locales/zh-hk.yml +1 -2
- data/config/locales/zh-tw.yml +1 -2
- data/config/locales/zh.yml +1 -2
- data/lib/generators/govuk_publishing_components/templates/_component.html.erb +1 -1
- data/lib/govuk_publishing_components/app_helpers/brand_helper.rb +1 -1
- data/lib/govuk_publishing_components/presenters/attachment_helper.rb +1 -3
- data/lib/govuk_publishing_components/presenters/public_layout_helper.rb +35 -16
- data/lib/govuk_publishing_components/version.rb +1 -1
- data/node_modules/govuk-frontend/govuk/all.js +120 -49
- data/node_modules/govuk-frontend/govuk/components/back-link/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/breadcrumbs/_index.scss +0 -2
- data/node_modules/govuk-frontend/govuk/components/breadcrumbs/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/button/_index.scss +6 -16
- data/node_modules/govuk-frontend/govuk/components/button/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/character-count/character-count.js +120 -49
- data/node_modules/govuk-frontend/govuk/components/character-count/fixtures.json +33 -17
- data/node_modules/govuk-frontend/govuk/components/character-count/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/character-count/template.njk +1 -4
- data/node_modules/govuk-frontend/govuk/components/checkboxes/_index.scss +3 -2
- data/node_modules/govuk-frontend/govuk/components/checkboxes/fixtures.json +22 -10
- data/node_modules/govuk-frontend/govuk/components/checkboxes/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/date-input/fixtures.json +23 -23
- data/node_modules/govuk-frontend/govuk/components/date-input/template.njk +1 -1
- data/node_modules/govuk-frontend/govuk/components/details/macro-options.json +4 -4
- data/node_modules/govuk-frontend/govuk/components/error-message/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/error-summary/macro-options.json +3 -3
- data/node_modules/govuk-frontend/govuk/components/fieldset/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/footer/_index.scss +12 -22
- data/node_modules/govuk-frontend/govuk/components/header/_index.scss +13 -3
- data/node_modules/govuk-frontend/govuk/components/header/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/hint/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/input/_index.scss +4 -13
- data/node_modules/govuk-frontend/govuk/components/input/macro-options.json +5 -5
- data/node_modules/govuk-frontend/govuk/components/inset-text/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/label/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/panel/_index.scss +1 -1
- data/node_modules/govuk-frontend/govuk/components/panel/macro-options.json +4 -4
- data/node_modules/govuk-frontend/govuk/components/phase-banner/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/radios/_index.scss +5 -4
- data/node_modules/govuk-frontend/govuk/components/radios/fixtures.json +17 -12
- data/node_modules/govuk-frontend/govuk/components/radios/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/skip-link/_index.scss +1 -3
- data/node_modules/govuk-frontend/govuk/components/skip-link/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/summary-list/macro-options.json +5 -5
- data/node_modules/govuk-frontend/govuk/components/table/macro-options.json +4 -4
- data/node_modules/govuk-frontend/govuk/components/tabs/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/tag/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/components/warning-text/macro-options.json +2 -2
- data/node_modules/govuk-frontend/govuk/helpers/_colour.scss +3 -3
- data/node_modules/govuk-frontend/govuk/helpers/_links.scss +7 -5
- data/node_modules/govuk-frontend/govuk/helpers/_media-queries.scss +2 -2
- data/node_modules/govuk-frontend/govuk/helpers/_shape-arrow.scss +1 -1
- data/node_modules/govuk-frontend/govuk/helpers/_spacing.scss +3 -3
- data/node_modules/govuk-frontend/govuk/helpers/_typography.scss +2 -2
- data/node_modules/govuk-frontend/govuk/objects/_button-group.scss +10 -26
- data/node_modules/govuk-frontend/govuk/objects/_template.scss +1 -1
- data/node_modules/govuk-frontend/govuk/objects/_width-container.scss +0 -4
- data/node_modules/govuk-frontend/govuk/tools/_exports.scss +1 -1
- data/node_modules/govuk-frontend/govuk/tools/_font-url.scss +1 -1
- data/node_modules/govuk-frontend/govuk/tools/_image-url.scss +1 -1
- data/node_modules/govuk-frontend/govuk/tools/_px-to-em.scss +2 -2
- data/node_modules/govuk-frontend/govuk/tools/_px-to-rem.scss +1 -1
- data/node_modules/govuk-frontend/govuk-esm/all.mjs +88 -0
- data/node_modules/govuk-frontend/govuk-esm/common.mjs +28 -0
- data/node_modules/govuk-frontend/govuk-esm/components/accordion/accordion.mjs +374 -0
- data/node_modules/govuk-frontend/govuk-esm/components/button/button.mjs +64 -0
- data/node_modules/govuk-frontend/govuk-esm/components/character-count/character-count.mjs +251 -0
- data/node_modules/govuk-frontend/govuk-esm/components/checkboxes/checkboxes.mjs +164 -0
- data/node_modules/govuk-frontend/govuk-esm/components/details/details.mjs +147 -0
- data/node_modules/govuk-frontend/govuk-esm/components/error-summary/error-summary.mjs +168 -0
- data/node_modules/govuk-frontend/govuk-esm/components/header/header.mjs +52 -0
- data/node_modules/govuk-frontend/govuk-esm/components/notification-banner/notification-banner.mjs +55 -0
- data/node_modules/govuk-frontend/govuk-esm/components/radios/radios.mjs +122 -0
- data/node_modules/govuk-frontend/govuk-esm/components/skip-link/skip-link.mjs +94 -0
- data/node_modules/govuk-frontend/govuk-esm/components/tabs/tabs.mjs +282 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/DOMTokenList.js +264 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Document.js +26 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Element/prototype/classList.js +93 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Element/prototype/closest.js +24 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Element/prototype/matches.js +23 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Element/prototype/nextElementSibling.js +22 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Element/prototype/previousElementSibling.js +22 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Element.js +114 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Event.js +252 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Function/prototype/bind.js +159 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Object/defineProperty.js +86 -0
- data/node_modules/govuk-frontend/govuk-esm/vendor/polyfills/Window.js +20 -0
- data/node_modules/govuk-frontend/package.json +8 -1
- metadata +30 -3
data/config/locales/pt.yml
CHANGED
data/config/locales/ro.yml
CHANGED
data/config/locales/ru.yml
CHANGED
data/config/locales/si.yml
CHANGED
data/config/locales/sk.yml
CHANGED
data/config/locales/sl.yml
CHANGED
data/config/locales/so.yml
CHANGED
data/config/locales/sq.yml
CHANGED
data/config/locales/sr.yml
CHANGED
data/config/locales/sv.yml
CHANGED
data/config/locales/sw.yml
CHANGED
data/config/locales/ta.yml
CHANGED
data/config/locales/th.yml
CHANGED
data/config/locales/tk.yml
CHANGED
data/config/locales/tr.yml
CHANGED
data/config/locales/uk.yml
CHANGED
data/config/locales/ur.yml
CHANGED
data/config/locales/uz.yml
CHANGED
data/config/locales/vi.yml
CHANGED
data/config/locales/zh-hk.yml
CHANGED
data/config/locales/zh-tw.yml
CHANGED
data/config/locales/zh.yml
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
<div class="<%= @component_prefix %><%= @public_name %>">
|
2
|
-
<h2><a href="https://github.com/alphagov/govuk_publishing_components/blob/
|
2
|
+
<h2><a href="https://github.com/alphagov/govuk_publishing_components/blob/main/docs/component_conventions.md">How to build a component</a></h2>
|
3
3
|
</div>
|
@@ -7,7 +7,7 @@ module GovukPublishingComponents
|
|
7
7
|
|
8
8
|
# Apply government organisation branding to individual components, specifically
|
9
9
|
# link colour and border colour
|
10
|
-
# see https://github.com/alphagov/govuk_publishing_components/blob/
|
10
|
+
# see https://github.com/alphagov/govuk_publishing_components/blob/main/docs/component_branding.md
|
11
11
|
|
12
12
|
def brand_class
|
13
13
|
"brand--#{@brand}" if @brand
|
@@ -6,9 +6,7 @@ module GovukPublishingComponents
|
|
6
6
|
# scheme is rolled out further this can be removed.
|
7
7
|
# Currently DfE, DWP and DVSA are participating in the pilot.
|
8
8
|
EMAILS_IN_ACCESSIBLE_FORMAT_REQUEST_PILOT = %w[govuk_publishing_components@example.com
|
9
|
-
alternative.formats@education.gov.uk
|
10
|
-
accessible.formats@dwp.gov.uk
|
11
|
-
gov.uk.publishing@dvsa.gov.uk].freeze
|
9
|
+
alternative.formats@education.gov.uk].freeze
|
12
10
|
|
13
11
|
delegate :opendocument?, :document?, :spreadsheet?, to: :content_type
|
14
12
|
|
@@ -2,7 +2,7 @@ module GovukPublishingComponents
|
|
2
2
|
module Presenters
|
3
3
|
class PublicLayoutHelper
|
4
4
|
FOOTER_NAVIGATION_COLUMNS = [2, 1].freeze
|
5
|
-
|
5
|
+
FOOTER_TRACK_ACTIONS = %w[topicsLink governmentActivityLink].freeze
|
6
6
|
FOOTER_META = {
|
7
7
|
items: [
|
8
8
|
{
|
@@ -46,25 +46,44 @@ module GovukPublishingComponents
|
|
46
46
|
attr_reader :footer_navigation, :footer_meta, :cookie_banner_data
|
47
47
|
|
48
48
|
def initialize(local_assigns)
|
49
|
-
@footer_navigation = local_assigns[:footer_navigation] || I18n.t("components.layout_footer.navigation_links")
|
49
|
+
@footer_navigation = local_assigns[:footer_navigation] || navigation_link_generation_from_locale(I18n.t("components.layout_footer.navigation_links"))
|
50
|
+
@footer_meta = local_assigns[:footer_meta] || { items: add_data_attributes_to_links(FOOTER_META[:items], "supportLink") }
|
51
|
+
@cookie_banner_data = local_assigns[:cookie_banner_data] || {}
|
52
|
+
end
|
53
|
+
|
54
|
+
def navigation_link_generation_from_locale(links)
|
55
|
+
links.each_with_index.map do |menu, i|
|
50
56
|
{
|
51
57
|
title: menu[:title],
|
52
|
-
columns:
|
53
|
-
items: menu[:menu_contents]
|
54
|
-
item.merge({
|
55
|
-
attributes: {
|
56
|
-
data: {
|
57
|
-
track_category: "footerClicked",
|
58
|
-
track_action: "footerLinks",
|
59
|
-
track_label: item[:text],
|
60
|
-
},
|
61
|
-
},
|
62
|
-
})
|
63
|
-
end,
|
58
|
+
columns: footer_navigation_columns[i],
|
59
|
+
items: add_data_attributes_to_links(menu[:menu_contents], footer_track_actions[i]),
|
64
60
|
}
|
65
61
|
end
|
66
|
-
|
67
|
-
|
62
|
+
end
|
63
|
+
|
64
|
+
def footer_navigation_columns
|
65
|
+
FOOTER_NAVIGATION_COLUMNS
|
66
|
+
end
|
67
|
+
|
68
|
+
def footer_track_actions
|
69
|
+
FOOTER_TRACK_ACTIONS
|
70
|
+
end
|
71
|
+
|
72
|
+
def generate_data_attribute(link, track_action)
|
73
|
+
{
|
74
|
+
track_category: "footerClicked",
|
75
|
+
track_action: track_action,
|
76
|
+
track_label: link[:href],
|
77
|
+
track_options: {
|
78
|
+
dimension29: link[:text],
|
79
|
+
},
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def add_data_attributes_to_links(items, track_action)
|
84
|
+
items.map do |item|
|
85
|
+
item.deep_merge({ attributes: { data: generate_data_attribute(item, track_action) } })
|
86
|
+
end
|
68
87
|
end
|
69
88
|
end
|
70
89
|
end
|
@@ -1601,9 +1601,9 @@ Details.prototype.polyfillHandleInputs = function (node, callback) {
|
|
1601
1601
|
function CharacterCount ($module) {
|
1602
1602
|
this.$module = $module;
|
1603
1603
|
this.$textarea = $module.querySelector('.govuk-js-character-count');
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1604
|
+
this.$visibleCountMessage = null;
|
1605
|
+
this.$screenReaderCountMessage = null;
|
1606
|
+
this.lastInputTimestamp = null;
|
1607
1607
|
}
|
1608
1608
|
|
1609
1609
|
CharacterCount.prototype.defaults = {
|
@@ -1613,18 +1613,39 @@ CharacterCount.prototype.defaults = {
|
|
1613
1613
|
|
1614
1614
|
// Initialize component
|
1615
1615
|
CharacterCount.prototype.init = function () {
|
1616
|
+
// Check that required elements are present
|
1617
|
+
if (!this.$textarea) {
|
1618
|
+
return
|
1619
|
+
}
|
1620
|
+
|
1616
1621
|
// Check for module
|
1617
1622
|
var $module = this.$module;
|
1618
1623
|
var $textarea = this.$textarea;
|
1619
|
-
var $
|
1620
|
-
|
1621
|
-
if (!$textarea || !$countMessage) {
|
1622
|
-
return
|
1623
|
-
}
|
1624
|
+
var $fallbackLimitMessage = document.getElementById($textarea.id + '-info');
|
1624
1625
|
|
1625
|
-
//
|
1626
|
+
// Move the fallback count message to be immediately after the textarea
|
1626
1627
|
// Kept for backwards compatibility
|
1627
|
-
$textarea.insertAdjacentElement('afterend', $
|
1628
|
+
$textarea.insertAdjacentElement('afterend', $fallbackLimitMessage);
|
1629
|
+
|
1630
|
+
// Create the *screen reader* specific live-updating counter
|
1631
|
+
// This doesn't need any styling classes, as it is never visible
|
1632
|
+
var $screenReaderCountMessage = document.createElement('div');
|
1633
|
+
$screenReaderCountMessage.className = 'govuk-character-count__sr-status govuk-visually-hidden';
|
1634
|
+
$screenReaderCountMessage.setAttribute('aria-live', 'polite');
|
1635
|
+
this.$screenReaderCountMessage = $screenReaderCountMessage;
|
1636
|
+
$fallbackLimitMessage.insertAdjacentElement('afterend', $screenReaderCountMessage);
|
1637
|
+
|
1638
|
+
// Create our live-updating counter element, copying the classes from the
|
1639
|
+
// fallback element for backwards compatibility as these may have been configured
|
1640
|
+
var $visibleCountMessage = document.createElement('div');
|
1641
|
+
$visibleCountMessage.className = $fallbackLimitMessage.className;
|
1642
|
+
$visibleCountMessage.classList.add('govuk-character-count__status');
|
1643
|
+
$visibleCountMessage.setAttribute('aria-hidden', 'true');
|
1644
|
+
this.$visibleCountMessage = $visibleCountMessage;
|
1645
|
+
$fallbackLimitMessage.insertAdjacentElement('afterend', $visibleCountMessage);
|
1646
|
+
|
1647
|
+
// Hide the fallback limit message
|
1648
|
+
$fallbackLimitMessage.classList.add('govuk-visually-hidden');
|
1628
1649
|
|
1629
1650
|
// Read options set using dataset ('data-' values)
|
1630
1651
|
this.options = this.getDataset($module);
|
@@ -1644,23 +1665,19 @@ CharacterCount.prototype.init = function () {
|
|
1644
1665
|
}
|
1645
1666
|
|
1646
1667
|
// Remove hard limit if set
|
1647
|
-
$
|
1668
|
+
$textarea.removeAttribute('maxlength');
|
1669
|
+
|
1670
|
+
this.bindChangeEvents();
|
1648
1671
|
|
1649
1672
|
// When the page is restored after navigating 'back' in some browsers the
|
1650
1673
|
// state of the character count is not restored until *after* the DOMContentLoaded
|
1651
|
-
// event is fired, so we need to
|
1652
|
-
// that support it.
|
1674
|
+
// event is fired, so we need to manually update it after the pageshow event
|
1675
|
+
// in browsers that support it.
|
1653
1676
|
if ('onpageshow' in window) {
|
1654
|
-
window.addEventListener('pageshow', this.
|
1677
|
+
window.addEventListener('pageshow', this.updateCountMessage.bind(this));
|
1655
1678
|
} else {
|
1656
|
-
window.addEventListener('DOMContentLoaded', this.
|
1679
|
+
window.addEventListener('DOMContentLoaded', this.updateCountMessage.bind(this));
|
1657
1680
|
}
|
1658
|
-
|
1659
|
-
this.sync();
|
1660
|
-
};
|
1661
|
-
|
1662
|
-
CharacterCount.prototype.sync = function () {
|
1663
|
-
this.bindChangeEvents();
|
1664
1681
|
this.updateCountMessage();
|
1665
1682
|
};
|
1666
1683
|
|
@@ -1695,7 +1712,7 @@ CharacterCount.prototype.count = function (text) {
|
|
1695
1712
|
// Bind input propertychange to the elements and update based on the change
|
1696
1713
|
CharacterCount.prototype.bindChangeEvents = function () {
|
1697
1714
|
var $textarea = this.$textarea;
|
1698
|
-
$textarea.addEventListener('keyup', this.
|
1715
|
+
$textarea.addEventListener('keyup', this.handleKeyUp.bind(this));
|
1699
1716
|
|
1700
1717
|
// Bind focus/blur events to start/stop polling
|
1701
1718
|
$textarea.addEventListener('focus', this.handleFocus.bind(this));
|
@@ -1713,42 +1730,64 @@ CharacterCount.prototype.checkIfValueChanged = function () {
|
|
1713
1730
|
}
|
1714
1731
|
};
|
1715
1732
|
|
1716
|
-
//
|
1733
|
+
// Helper function to update both the visible and screen reader-specific
|
1734
|
+
// counters simultaneously (e.g. on init)
|
1717
1735
|
CharacterCount.prototype.updateCountMessage = function () {
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1736
|
+
this.updateVisibleCountMessage();
|
1737
|
+
this.updateScreenReaderCountMessage();
|
1738
|
+
};
|
1721
1739
|
|
1722
|
-
|
1723
|
-
|
1724
|
-
var
|
1725
|
-
var
|
1740
|
+
// Update visible counter
|
1741
|
+
CharacterCount.prototype.updateVisibleCountMessage = function () {
|
1742
|
+
var $textarea = this.$textarea;
|
1743
|
+
var $visibleCountMessage = this.$visibleCountMessage;
|
1744
|
+
var remainingNumber = this.maxLength - this.count($textarea.value);
|
1726
1745
|
|
1727
|
-
//
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
countMessage.classList.add('govuk-character-count__message--disabled');
|
1732
|
-
// Ensure threshold is hidden for users of assistive technologies
|
1733
|
-
countMessage.setAttribute('aria-hidden', true);
|
1746
|
+
// If input is over the threshold, remove the disabled class which renders the
|
1747
|
+
// counter invisible.
|
1748
|
+
if (this.isOverThreshold()) {
|
1749
|
+
$visibleCountMessage.classList.remove('govuk-character-count__message--disabled');
|
1734
1750
|
} else {
|
1735
|
-
|
1736
|
-
// Ensure threshold is visible for users of assistive technologies
|
1737
|
-
countMessage.removeAttribute('aria-hidden');
|
1751
|
+
$visibleCountMessage.classList.add('govuk-character-count__message--disabled');
|
1738
1752
|
}
|
1739
1753
|
|
1740
1754
|
// Update styles
|
1741
1755
|
if (remainingNumber < 0) {
|
1742
|
-
|
1743
|
-
|
1744
|
-
|
1756
|
+
$textarea.classList.add('govuk-textarea--error');
|
1757
|
+
$visibleCountMessage.classList.remove('govuk-hint');
|
1758
|
+
$visibleCountMessage.classList.add('govuk-error-message');
|
1759
|
+
} else {
|
1760
|
+
$textarea.classList.remove('govuk-textarea--error');
|
1761
|
+
$visibleCountMessage.classList.remove('govuk-error-message');
|
1762
|
+
$visibleCountMessage.classList.add('govuk-hint');
|
1763
|
+
}
|
1764
|
+
|
1765
|
+
// Update message
|
1766
|
+
$visibleCountMessage.innerHTML = this.formattedUpdateMessage();
|
1767
|
+
};
|
1768
|
+
|
1769
|
+
// Update screen reader-specific counter
|
1770
|
+
CharacterCount.prototype.updateScreenReaderCountMessage = function () {
|
1771
|
+
var $screenReaderCountMessage = this.$screenReaderCountMessage;
|
1772
|
+
|
1773
|
+
// If over the threshold, remove the aria-hidden attribute, allowing screen
|
1774
|
+
// readers to announce the content of the element.
|
1775
|
+
if (this.isOverThreshold()) {
|
1776
|
+
$screenReaderCountMessage.removeAttribute('aria-hidden');
|
1745
1777
|
} else {
|
1746
|
-
|
1747
|
-
countMessage.classList.remove('govuk-error-message');
|
1748
|
-
countMessage.classList.add('govuk-hint');
|
1778
|
+
$screenReaderCountMessage.setAttribute('aria-hidden', true);
|
1749
1779
|
}
|
1750
1780
|
|
1751
1781
|
// Update message
|
1782
|
+
$screenReaderCountMessage.innerHTML = this.formattedUpdateMessage();
|
1783
|
+
};
|
1784
|
+
|
1785
|
+
// Format update message
|
1786
|
+
CharacterCount.prototype.formattedUpdateMessage = function () {
|
1787
|
+
var $textarea = this.$textarea;
|
1788
|
+
var options = this.options;
|
1789
|
+
var remainingNumber = this.maxLength - this.count($textarea.value);
|
1790
|
+
|
1752
1791
|
var charVerb = 'remaining';
|
1753
1792
|
var charNoun = 'character';
|
1754
1793
|
var displayNumber = remainingNumber;
|
@@ -1760,12 +1799,44 @@ CharacterCount.prototype.updateCountMessage = function () {
|
|
1760
1799
|
charVerb = (remainingNumber < 0) ? 'too many' : 'remaining';
|
1761
1800
|
displayNumber = Math.abs(remainingNumber);
|
1762
1801
|
|
1763
|
-
|
1802
|
+
return 'You have ' + displayNumber + ' ' + charNoun + ' ' + charVerb
|
1803
|
+
};
|
1804
|
+
|
1805
|
+
// Checks whether the value is over the configured threshold for the input.
|
1806
|
+
// If there is no configured threshold, it is set to 0 and this function will
|
1807
|
+
// always return true.
|
1808
|
+
CharacterCount.prototype.isOverThreshold = function () {
|
1809
|
+
var $textarea = this.$textarea;
|
1810
|
+
var options = this.options;
|
1811
|
+
|
1812
|
+
// Determine the remaining number of characters/words
|
1813
|
+
var currentLength = this.count($textarea.value);
|
1814
|
+
var maxLength = this.maxLength;
|
1815
|
+
|
1816
|
+
// Set threshold if presented in options
|
1817
|
+
var thresholdPercent = options.threshold ? options.threshold : 0;
|
1818
|
+
var thresholdValue = maxLength * thresholdPercent / 100;
|
1819
|
+
|
1820
|
+
return (thresholdValue <= currentLength)
|
1821
|
+
};
|
1822
|
+
|
1823
|
+
// Update the visible character counter and keep track of when the last update
|
1824
|
+
// happened for each keypress
|
1825
|
+
CharacterCount.prototype.handleKeyUp = function () {
|
1826
|
+
this.updateVisibleCountMessage();
|
1827
|
+
this.lastInputTimestamp = Date.now();
|
1764
1828
|
};
|
1765
1829
|
|
1766
1830
|
CharacterCount.prototype.handleFocus = function () {
|
1767
|
-
//
|
1768
|
-
|
1831
|
+
// If the field is focused, and a keyup event hasn't been detected for at
|
1832
|
+
// least 1000 ms (1 second), then run the manual change check.
|
1833
|
+
// This is so that the update triggered by the manual comparison doesn't
|
1834
|
+
// conflict with debounced KeyboardEvent updates.
|
1835
|
+
this.valueChecker = setInterval(function () {
|
1836
|
+
if (!this.lastInputTimestamp || (Date.now() - 500) >= this.lastInputTimestamp) {
|
1837
|
+
this.checkIfValueChanged();
|
1838
|
+
}
|
1839
|
+
}.bind(this), 1000);
|
1769
1840
|
};
|
1770
1841
|
|
1771
1842
|
CharacterCount.prototype.handleBlur = function () {
|
@@ -3,13 +3,13 @@
|
|
3
3
|
"name": "text",
|
4
4
|
"type": "string",
|
5
5
|
"required": false,
|
6
|
-
"description": "Text to use within the back link component. If `html` is provided, the `text`
|
6
|
+
"description": "Text to use within the back link component. If `html` is provided, the `text` option will be ignored. Defaults to 'Back'."
|
7
7
|
},
|
8
8
|
{
|
9
9
|
"name": "html",
|
10
10
|
"type": "string",
|
11
11
|
"required": false,
|
12
|
-
"description": "HTML to use within the back link component. If `html` is provided, the `text`
|
12
|
+
"description": "HTML to use within the back link component. If `html` is provided, the `text` option will be ignored. Defaults to 'Back'."
|
13
13
|
},
|
14
14
|
{
|
15
15
|
"name": "href",
|
@@ -9,13 +9,13 @@
|
|
9
9
|
"name": "text",
|
10
10
|
"type": "string",
|
11
11
|
"required": true,
|
12
|
-
"description": "If `html` is set, this is not required. Text to use within the breadcrumbs item. If `html` is provided, the `text`
|
12
|
+
"description": "If `html` is set, this is not required. Text to use within the breadcrumbs item. If `html` is provided, the `text` option will be ignored."
|
13
13
|
},
|
14
14
|
{
|
15
15
|
"name": "html",
|
16
16
|
"type": "string",
|
17
17
|
"required": true,
|
18
|
-
"description": "If `text` is set, this is not required. HTML to use within the breadcrumbs item. If `html` is provided, the `text`
|
18
|
+
"description": "If `text` is set, this is not required. HTML to use within the breadcrumbs item. If `html` is provided, the `text` option will be ignored."
|
19
19
|
},
|
20
20
|
{
|
21
21
|
"name": "href",
|