Skip to content

Commit

Permalink
Modify subscription links component
Browse files Browse the repository at this point in the history
- add option to change link text
- add option to turn feed link into a toggle to display an input box containing a link
- includes toggle.js from static, included without changes
  • Loading branch information
andysellick committed May 2, 2018
1 parent 13ab0d6 commit fc75a6d
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Unreleased

- Modify subscription links component (PR #294)

# 7.1.0

* Add subscription links component (PR #290)
Expand Down
69 changes: 69 additions & 0 deletions app/assets/javascripts/govuk_publishing_components/lib/toggle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
Toggle the display of elements
This is a straight copy of the same file from static.
Use `data-controls` and `data-expanded` to indicate the
starting state and the IDs of the elements that the toggle
controls. This is synonymous with ARIA attributes, which
get added when starting.
*/

window.GOVUK.Modules = window.GOVUK.Modules || {};

(function (Modules) {
'use strict'

Modules.GemToggle = function () {
this.start = function ($el) {
var toggleSelector = '[data-controls][data-expanded]'

$el.on('click', toggleSelector, toggle)
$el.find(toggleSelector).each(addAriaAttrs)

// Add the ARIA attributes with JavaScript
// If the JS fails and there's no interactive elements, having
// no aria attributes is an accurate representation.
function addAriaAttrs () {
var $toggle = $(this)
$toggle.attr('role', 'button')
$toggle.attr('aria-controls', $toggle.data('controls'))
$toggle.attr('aria-expanded', $toggle.data('expanded'))

var $targets = getTargetElements($toggle)
$targets.attr('aria-live', 'polite')
$targets.attr('role', 'region')
$toggle.data('$targets', $targets)
}

function toggle (event) {
var $toggle = $(event.target),
expanded = $toggle.attr('aria-expanded') === 'true',
$targets = $toggle.data('$targets')

if (expanded) {
$toggle.attr('aria-expanded', false)
$targets.addClass('js-hidden')
} else {
$toggle.attr('aria-expanded', true)
$targets.removeClass('js-hidden')
}

var toggledText = $toggle.data('toggled-text')
if (typeof toggledText === 'string') {
$toggle.data('toggled-text', $toggle.text())
$toggle.text(toggledText)
}

event.preventDefault()
}

function getTargetElements ($toggle) {
var ids = $toggle.attr('aria-controls').split(' '),
selector = '#' + ids.join(', #')

return $el.find(selector)
}
}
}
})(window.GOVUK.Modules)
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,9 @@
}
}
}

.gem-c-subscription-links__feed-box {
padding: $gutter-half;
margin-top: $gutter-one-quarter;
background: $grey-3;
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
<%
email_signup_link ||= false
email_signup_link_text ||= "Get email alerts"
feed_link ||= false
feed_link_text ||= "Subscribe to feed"
feed_link_box_value ||= false
%>
<% if email_signup_link || feed_link %>
<% if email_signup_link || feed_link || feed_link_box_value %>
<section class="gem-c-subscription-links">
<h2 class="visuallyhidden">Subscriptions</h2>
<ul class="gem-c-subscription-links__list">
<% if email_signup_link.present? %>
<li class="gem-c-subscription-links__list-item">
<%= link_to "Get email alerts", email_signup_link, class: "gem-c-subscription-links__link gem-c-subscription-links__link--email-alerts" %>
<%= link_to email_signup_link_text, email_signup_link, class: "gem-c-subscription-links__link gem-c-subscription-links__link--email-alerts" %>
</li>
<% end %>
<% if feed_link.present? %>

<% if feed_link_box_value %>
<li class="gem-c-subscription-links__list-item" data-module="gem-toggle">
<%= link_to feed_link_text, "#",
class: "gem-c-subscription-links__link gem-c-subscription-links__link--feed",
data: {
controls: "feed-reader",
expanded: "false"
}
%>
<div class="gem-c-subscription-links__feed-box js-hidden" id="feed-reader">
<%= render "govuk_publishing_components/components/input", {
label: {
text: "Copy and paste this URL into your feed reader"
},
name: "feed-reader-box",
value: feed_link_box_value
} %>
</div>
</li>
<% elsif feed_link.present? %>
<li class="gem-c-subscription-links__list-item">
<%= link_to "Subscribe to feed", feed_link, class: "gem-c-subscription-links__link gem-c-subscription-links__link--feed" %>
<%= link_to feed_link_text, feed_link, class: "gem-c-subscription-links__link gem-c-subscription-links__link--feed" %>
</li>
<% end %>
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,16 @@ examples:
with_only_feed_link:
data:
feed_link: '/foreign-travel-advice/singapore.atom'
with_custom_text:
data:
email_signup_link: '/foreign-travel-advice/singapore/email-signup'
email_signup_link_text: 'Get notifications'
feed_link: '/foreign-travel-advice/singapore.atom'
feed_link_text: 'View feed'
with_copyable_feed_link:
description: |
This option changes the feed link to a toggle control, which opens a hidden element containing an input containing the value passed to the component, usually a URL to an atom feed. This uses the [form input](/component-guide/input) component.
Note that this option overrides the feed_link option, so if both are passed feed_link is ignored. Note that a value for email_signup_link can also be passed as normal.
data:
feed_link_box_value: 'https://www.gov.uk/government/organisations/attorney-generals-office.atom'
12 changes: 12 additions & 0 deletions spec/components/subscription_links_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,16 @@ def component_name
assert_select ".gem-c-subscription-links__link--email-alerts[href=\"email-signup\"]", text: "Get email alerts"
assert_select ".gem-c-subscription-links__link--feed[href=\"singapore.atom\"]", text: "Subscribe to feed"
end

it "renders custom texts" do
render_component(email_signup_link: 'email-signup', feed_link: 'singapore.atom', email_signup_link_text: 'Get email!', feed_link_text: 'View feed!')
assert_select ".gem-c-subscription-links__link--email-alerts[href=\"email-signup\"]", text: "Get email!"
assert_select ".gem-c-subscription-links__link--feed[href=\"singapore.atom\"]", text: "View feed!"
end

it "renders with a feed link box" do
render_component(feed_link_box_value: 'http://www.gov.uk', feed_link: 'singapore.atom')
assert_select ".gem-c-subscription-links__link--feed[href=\"singapore.atom\"]", false
assert_select ".gem-c-subscription-links__feed-box input[name='feed-reader-box'][value='http://www.gov.uk']"
end
end
86 changes: 86 additions & 0 deletions spec/javascripts/components/toggle-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
describe('A toggle module', function () {
'use strict'

var toggle,
element

beforeEach(function () {
toggle = new GOVUK.Modules.GemToggle()
})

describe('when starting', function () {
var element = $('\
<div>\
<a href="#" class="my-toggle" data-expanded="false" data-controls="target">Toggle</a>\
<div id="target">Target</div>\
</div>')

it('adds aria attributes to toggles', function () {
toggle.start(element)

var $toggle = element.find('.my-toggle')
expect($toggle.attr('role')).toBe('button')
expect($toggle.attr('aria-expanded')).toBe('false')
expect($toggle.attr('aria-controls')).toBe('target')
})
})

describe('when clicking a toggle', function () {
var element

beforeEach(function () {
element = $('\
<div>\
<a href="#" class="my-toggle" data-expanded="false" data-controls="target" data-toggled-text="Show fewer">Toggle</a>\
<div id="target" class="js-hidden">Target</div>\
</div>')

toggle.start(element)
element.find('.my-toggle').trigger('click')
})

it('toggles the display of a target', function () {
expect(element.find('#target').is('.js-hidden')).toBe(false)
element.find('.my-toggle').trigger('click')
expect(element.find('#target').is('.js-hidden')).toBe(true)
})

it('updates the aria-expanded attribute on the toggle', function () {
expect(element.find('.my-toggle').attr('aria-expanded')).toBe('true')

element.find('.my-toggle').trigger('click')
expect(element.find('.my-toggle').attr('aria-expanded')).toBe('false')
})

it('updates the text shown in the toggle link when expanded if such text is supplied', function () {
expect(element.find('.my-toggle').data('toggled-text')).toBe('Toggle')
expect(element.find('.my-toggle').text()).toBe('Show fewer')
element.find('.my-toggle').trigger('click')
expect(element.find('.my-toggle').data('toggled-text')).toBe('Show fewer')
expect(element.find('.my-toggle').text()).toBe('Toggle')
})
})

describe('when clicking a toggle that controls multiple targets', function () {
it('toggles the display of each target', function () {
var element = $('\
<div>\
<a href="#" class="my-toggle" data-expanded="false" data-controls="target another-target">Toggle</a>\
<div id="target" class="js-hidden">Target</div>\
<div id="another-target" class="js-hidden">Another target</div>\
</div>')

toggle.start(element)
expect(element.find('#target').is('.js-hidden')).toBe(true)
expect(element.find('#another-target').is('.js-hidden')).toBe(true)

element.find('.my-toggle').trigger('click')
expect(element.find('#target').is('.js-hidden')).toBe(false)
expect(element.find('#another-target').is('.js-hidden')).toBe(false)

element.find('.my-toggle').trigger('click')
expect(element.find('#target').is('.js-hidden')).toBe(true)
expect(element.find('#another-target').is('.js-hidden')).toBe(true)
})
})
})

0 comments on commit fc75a6d

Please sign in to comment.