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

Release v2.2.0 #1029

Merged
merged 1 commit into from
Oct 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@

🆕 New features:

- Pull Request Title goes here

Description goes here (optional)

([PR #N](https://github.com/alphagov/govuk-frontend/pull/N))

🔧 Fixes:

- Pull Request Title goes here

Description goes here (optional)

([PR #N](https://github.com/alphagov/govuk-frontend/pull/N))

## 2.2.0 (Feature release)

🆕 New features:

- Allow classes on table header and row cells

Optional classes attribute can now be used on table header and row cell item
Expand Down Expand Up @@ -58,12 +76,6 @@

([PR #1020](https://github.com/alphagov/govuk-frontend/pull/1020))

- Pull Request Title goes here

Description goes here (optional)

([PR #N](https://github.com/alphagov/govuk-frontend/pull/N))

## 2.1.0 (Feature release)

🆕 New features:
Expand Down
2 changes: 1 addition & 1 deletion dist/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.1.0
2.2.0
3 changes: 0 additions & 3 deletions dist/govuk-frontend-2.1.0.min.css

This file was deleted.

1 change: 0 additions & 1 deletion dist/govuk-frontend-2.1.0.min.js

This file was deleted.

3 changes: 3 additions & 0 deletions dist/govuk-frontend-2.2.0.min.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/govuk-frontend-2.2.0.min.js

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions dist/govuk-frontend-ie8-2.1.0.min.css

This file was deleted.

3 changes: 3 additions & 0 deletions dist/govuk-frontend-ie8-2.2.0.min.css

Large diffs are not rendered by default.

188 changes: 188 additions & 0 deletions package/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,188 @@ Details.prototype.destroy = function (node) {

}).call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});

function CharacterCount ($module) {
this.$module = $module;
this.$textarea = $module.querySelector('.js-character-count');
}

CharacterCount.prototype.defaults = {
characterCountAttribute: 'data-maxlength',
wordCountAttribute: 'data-maxwords'
};

// Initialize component
CharacterCount.prototype.init = function () {
// Check for module
var $module = this.$module;
var $textarea = this.$textarea;
if (!$textarea) {
return
}

// Read options set using dataset ('data-' values)
this.options = this.getDataset($module);

// Determine the limit attribute (characters or words)
var countAttribute = this.defaults.characterCountAttribute;
if (this.options.maxwords) {
countAttribute = this.defaults.wordCountAttribute;
}

// Save the element limit
this.maxLength = $module.getAttribute(countAttribute);

// Check for limit
if (!this.maxLength) {
return
}

// Generate and reference message
var boundCreateCountMessage = this.createCountMessage.bind(this);
this.countMessage = boundCreateCountMessage();

// If there's a maximum length defined and the count message exists
if (this.countMessage) {
// Remove hard limit if set
$module.removeAttribute('maxlength');

// Bind event changes to the textarea
var boundChangeEvents = this.bindChangeEvents.bind(this);
boundChangeEvents();

// Update count message
var boundUpdateCountMessage = this.updateCountMessage.bind(this);
boundUpdateCountMessage();
}
};

// Read data attributes
CharacterCount.prototype.getDataset = function (element) {
var dataset = {};
var attributes = element.attributes;
if (attributes) {
for (var i = 0; i < attributes.length; i++) {
var attribute = attributes[i];
var match = attribute.name.match(/^data-(.+)/);
if (match) {
dataset[match[1]] = attribute.value;
}
}
}
return dataset
};

// Counts characters or words in text
CharacterCount.prototype.count = function (text) {
var length;
if (this.options.maxwords) {
var tokens = text.match(/\S+/g) || []; // Matches consecutive non-whitespace chars
length = tokens.length;
} else {
length = text.length;
}
return length
};

// Generate count message and bind it to the input
// returns reference to the generated element
CharacterCount.prototype.createCountMessage = function () {
var countElement = this.$textarea;
var elementId = countElement.id;
// Check for existing info count message
var countMessage = document.getElementById(elementId + '-info');
// If there is no existing info count message we add one right after the field
if (elementId && !countMessage) {
countElement.insertAdjacentHTML('afterend', '<span id="' + elementId + '-info" class="govuk-hint govuk-character-count__message" aria-live="polite"></span>');
this.describedBy = countElement.getAttribute('aria-describedby');
this.describedByInfo = this.describedBy + ' ' + elementId + '-info';
countElement.setAttribute('aria-describedby', this.describedByInfo);
countMessage = document.getElementById(elementId + '-info');
} else {
// If there is an existing info count message we move it right after the field
countElement.insertAdjacentElement('afterend', countMessage);
}
return countMessage
};

// Bind input propertychange to the elements and update based on the change
CharacterCount.prototype.bindChangeEvents = function () {
var $textarea = this.$textarea;
$textarea.addEventListener('keyup', this.checkIfValueChanged.bind(this));

// Bind focus/blur events to start/stop polling
$textarea.addEventListener('focus', this.handleFocus.bind(this));
$textarea.addEventListener('blur', this.handleBlur.bind(this));
};

// Speech recognition software such as Dragon NaturallySpeaking will modify the
// fields by directly changing its `value`. These changes don't trigger events
// in JavaScript, so we need to poll to handle when and if they occur.
CharacterCount.prototype.checkIfValueChanged = function () {
if (!this.$textarea.oldValue) this.$textarea.oldValue = '';
if (this.$textarea.value !== this.$textarea.oldValue) {
this.$textarea.oldValue = this.$textarea.value;
var boundUpdateCountMessage = this.updateCountMessage.bind(this);
boundUpdateCountMessage();
}
};

// Update message box
CharacterCount.prototype.updateCountMessage = function () {
var countElement = this.$textarea;
var options = this.options;
var countMessage = this.countMessage;

// Determine the remaining number of characters/words
var currentLength = this.count(countElement.value);
var maxLength = this.maxLength;
var remainingNumber = maxLength - currentLength;

// Set threshold if presented in options
var thresholdPercent = options.threshold ? options.threshold : 0;
var thresholdValue = maxLength * thresholdPercent / 100;
if (thresholdValue > currentLength) {
countMessage.classList.add('govuk-character-count__message--disabled');
} else {
countMessage.classList.remove('govuk-character-count__message--disabled');
}

// Update styles
if (remainingNumber < 0) {
countElement.classList.add('govuk-textarea--error');
countMessage.classList.remove('govuk-hint');
countMessage.classList.add('govuk-error-message');
} else {
countElement.classList.remove('govuk-textarea--error');
countMessage.classList.remove('govuk-error-message');
countMessage.classList.add('govuk-hint');
}

// Update message
var charVerb = 'remaining';
var charNoun = 'character';
var displayNumber = remainingNumber;
if (options.maxwords) {
charNoun = 'word';
}
charNoun = charNoun + ((remainingNumber === -1 || remainingNumber === 1) ? '' : 's');

charVerb = (remainingNumber < 0) ? 'too many' : 'remaining';
displayNumber = Math.abs(remainingNumber);

countMessage.innerHTML = 'You have ' + displayNumber + ' ' + charNoun + ' ' + charVerb;
};

CharacterCount.prototype.handleFocus = function () {
// Check if value changed on focus
this.valueChecker = setInterval(this.checkIfValueChanged.bind(this), 1000);
};

CharacterCount.prototype.handleBlur = function () {
// Cancel value checking on blur
clearInterval(this.valueChecker);
};

function Checkboxes ($module) {
this.$module = $module;
this.$inputs = $module.querySelectorAll('input[type="checkbox"]');
Expand Down Expand Up @@ -1688,6 +1870,11 @@ function initAll () {
new Details($detail).init();
});

var $characterCount = document.querySelectorAll('[data-module="character-count"]');
nodeListForEach($characterCount, function ($characterCount) {
new CharacterCount($characterCount).init();
});

var $checkboxes = document.querySelectorAll('[data-module="checkboxes"]');
nodeListForEach($checkboxes, function ($checkbox) {
new Checkboxes($checkbox).init();
Expand Down Expand Up @@ -1715,6 +1902,7 @@ function initAll () {
exports.initAll = initAll;
exports.Button = Button;
exports.Details = Details;
exports.CharacterCount = CharacterCount;
exports.Checkboxes = Checkboxes;
exports.ErrorSummary = ErrorSummary;
exports.Header = Header;
Expand Down
1 change: 1 addition & 0 deletions package/components/_all.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@import "breadcrumbs/breadcrumbs";
@import "button/button";
@import "checkboxes/checkboxes";
@import "character-count/character-count";
@import "date-input/date-input";
@import "details/details";
@import "error-message/error-message";
Expand Down
24 changes: 12 additions & 12 deletions package/components/back-link/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,47 +89,47 @@ If you are using Nunjucks,then macros take the following arguments

<th class="govuk-table__header" scope="row">text (or) html</th>

<td class="govuk-table__cell ">string</td>
<td class="govuk-table__cell">string</td>

<td class="govuk-table__cell ">Yes</td>
<td class="govuk-table__cell">Yes</td>

<td class="govuk-table__cell ">Text or HTML to use within the back link component. If `html` is provided, the `text` argument will be ignored.</td>
<td class="govuk-table__cell">Text or HTML to use within the back link component. If `html` is provided, the `text` argument will be ignored.</td>

</tr>

<tr class="govuk-table__row">

<th class="govuk-table__header" scope="row">href</th>

<td class="govuk-table__cell ">string</td>
<td class="govuk-table__cell">string</td>

<td class="govuk-table__cell ">Yes</td>
<td class="govuk-table__cell">Yes</td>

<td class="govuk-table__cell ">The value of the link href attribute</td>
<td class="govuk-table__cell">The value of the link href attribute</td>

</tr>

<tr class="govuk-table__row">

<th class="govuk-table__header" scope="row">classes</th>

<td class="govuk-table__cell ">string</td>
<td class="govuk-table__cell">string</td>

<td class="govuk-table__cell ">No</td>
<td class="govuk-table__cell">No</td>

<td class="govuk-table__cell ">Optional additional classes to add to the anchor tag.</td>
<td class="govuk-table__cell">Optional additional classes to add to the anchor tag.</td>

</tr>

<tr class="govuk-table__row">

<th class="govuk-table__header" scope="row">attributes</th>

<td class="govuk-table__cell ">object</td>
<td class="govuk-table__cell">object</td>

<td class="govuk-table__cell ">No</td>
<td class="govuk-table__cell">No</td>

<td class="govuk-table__cell ">Any extra HTML attributes (for example data attributes) to add to the anchor tag.</td>
<td class="govuk-table__cell">Any extra HTML attributes (for example data attributes) to add to the anchor tag.</td>

</tr>

Expand Down
Loading