Skip to content

Commit

Permalink
[refs #320] Initial setup and styling for autocomplete
Browse files Browse the repository at this point in the history
Add the GOV.UK autocomplete dependency connected to the NHS.UK
funnelback search autocomplete. Also add some default styling
for the autocomplete dropdown that needs finishing.
  • Loading branch information
chrimesdev committed Jan 2, 2019
1 parent 937317b commit dfe5f79
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 42 deletions.
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"build-gh-release": "gulp zip"
},
"dependencies": {
"accessible-autocomplete": "^1.6.2",
"sass-mq": "^4.0.2"
},
"devDependencies": {
Expand Down
90 changes: 48 additions & 42 deletions packages/components/header/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@

}

.autocomplete-container {
display: inline-block;
}

.nhsuk-header__search {
@include clearfix();

Expand Down Expand Up @@ -149,6 +153,7 @@
width: 100%;
}

.autocomplete__input,
.nhsuk-search__input {
-ms-flex-positive: 2; /* [14] */
-webkit-appearance: listbox; // sass-lint:disable-line prefixes /* [5] */
Expand Down Expand Up @@ -233,6 +238,7 @@
display: none;
}

.autocomplete__input,
.nhsuk-search__input {
-webkit-appearance: listbox; // sass-lint:disable-line prefixes /* [5] */
background-color: $color_nhsuk-white !important; // sass-lint:disable-line no-important /* [6] */
Expand Down Expand Up @@ -319,42 +325,45 @@
border-bottom-right-radius: 0;
}

/**
* Autocomplete
**/

.twitter-typeahead {
display: inline !important; // sass-lint:disable-line no-important /* [6] */
width: 100%;
.autocomplete__wrapper {
position: relative;
}

.suggestions-list {
-moz-box-shadow: 0 3px 5px 0 rgba($nhsuk-box-shadow-color, $alpha-transparency-50); // sass-lint:disable-line no-vendor-prefixes, no-color-literals /* [8] */
-webkit-box-shadow: 0 3px 5px 0 rgba($nhsuk-box-shadow-color, $alpha-transparency-50); // sass-lint:disable-line no-vendor-prefixes, no-color-literals /* [8] */
.autocomplete__input {
background-color: transparent;
position: relative;
}

.autocomplete__menu {
// sass-lint:disable-block no-vendor-prefixes, no-color-literals
-moz-box-shadow: 0 3px 5px 0 rgba($nhsuk-box-shadow-color, $alpha-transparency-50); /* [8] */
-webkit-box-shadow: 0 3px 5px 0 rgba($nhsuk-box-shadow-color, $alpha-transparency-50); /* [8] */
background-color: $color_nhsuk-white;
border-bottom: 1px solid $color_nhsuk-grey-4;
border-bottom-left-radius: $nhsuk-border-radius;
border-bottom-right-radius: $nhsuk-border-radius;
border-left: 1px solid $color_nhsuk-grey-4;
border-right: 1px solid $color_nhsuk-grey-4;
border-top: 2px solid $color_nhsuk-blue;
box-shadow: 0 0 ($nhsuk-box-shadow-spread - 1) 0 rgba($nhsuk-box-shadow-color, $alpha-transparency-50); // sass-lint:disable-line no-color-literals /* [8] */
box-shadow: 0 0 ($nhsuk-box-shadow-spread - 1) 0 rgba($nhsuk-box-shadow-color, $alpha-transparency-50); /* [8] */
height: auto;
list-style: none;
margin-top: 0;
overflow-x: hidden;
overflow-y: auto;
padding: nhsuk-spacing(2) nhsuk-spacing(3) nhsuk-spacing(3);
position: absolute;
position: fixed;
top: 60px;
width: 235px;
z-index: 1; /* [10] */
}


@include mq($until: tablet) {

.suggestions-menu {
position: relative !important; // sass-lint:disable-line no-important /* [6] */
top: 0 !important; // sass-lint:disable-line no-important /* [6] */
}

.suggestions-list {
.autocomplete__menu {
border: 0;
border-radius: 0;
box-shadow: none;
Expand All @@ -368,41 +377,45 @@

}

.suggestions-item {
.autocomplete__option {
border-bottom: 1px solid $color_nhsuk-grey-5;
color: $color_nhsuk-blue;
cursor: pointer;
font-size: $nhsuk-base-font-size;
font-weight: $nhsuk-font-light;
padding-bottom: 12px; /* [9] */
text-align: left;
text-decoration: underline;

.nhsuk-icon__search {
fill: $color_nhsuk-grey-3;
float: left;
height: 22px; /* [2] */
margin: 5px 4px 0 0; /* [7] */
width: 22px; /* [2] */
}

&:hover,
&:active {
text-decoration: none;
}

&:hover,
&:focus {
div {
background-color: $color_nhsuk-warm-yellow;
box-shadow: 0 0 0 $nhsuk-box-shadow-spread $color_nhsuk-warm-yellow;
color: $color_nhsuk-black;
display: inline;
}
}
}

.autocomplete__option--no-results {
border-bottom: 0;
color: $color_nhsuk-black;
font-size: $nhsuk-base-font-size;
line-height: $nhsuk-base-line-height;
margin: 0;
padding: 0;
text-align: left;
text-decoration: none;
}

.autocomplete__menu--visible {
display: block;
}

.autocomplete__menu--hidden {
display: none;
}

/**
* Typeahead autocomplete
**/

.suggestions-item--selected {
a {
background-color: $color_nhsuk-warm-yellow;
Expand All @@ -422,13 +435,6 @@
text-align: left;
}

.suggestions-none {
font-size: $nhsuk-base-font-size;
line-height: $nhsuk-base-line-height;
margin: 0;
text-align: left;
}

/* Main navigation
*
* Appears below the header strip
Expand Down
80 changes: 80 additions & 0 deletions packages/components/header/autocomplete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import accessibleAutocomplete from 'accessible-autocomplete';

function getFunnelbackQueryUrl(query) {
const FUNNELBACK_QUERY_PATH = 'https://nhs.funnelback.co.uk/s/suggest.json';
const FUNNELBACK_MAX_RESULTS = 10;
return `${FUNNELBACK_QUERY_PATH}?collection=nhs-meta&partial_query=${query}&sort=0&fmt=json++&profile=&show=${FUNNELBACK_MAX_RESULTS}`;
}

function getFunnelbackResults(query, populateResults) {
const url = getFunnelbackQueryUrl(query);
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = function () {
if (xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
const results = data.map(item => {
return item.disp;
});
populateResults(results);
} else {
// TODO: nice error messaging here
// console.warn(xhr);
}
};
xhr.send();
}

function autocomplete(config) {
const defaultId = 'search-field';
const id = (config && config.id) ? config.id : defaultId;

const fallbackInputElement = document.getElementById(id);

function suggestionTemplate(result) {
const truncateLength = 36;
const dots = result.length > truncateLength ? '...' : '';
result = result.substring(0, truncateLength) + dots;

if (!result) {
return '';
}

var TypedText = document.getElementById(id).value;
var expr = TypedText;
expr = expr.replace(/\s+/, '|', TypedText);
var regex = new RegExp(expr, 'gi');
result = '<a href="">' + result + '</a>';
return result.replace(regex, function ($1) {
return '<b>' + $1 + '</b>';
});
}

const defaultConfig = {
element: document.querySelector('#autocomplete-container'),
id: id,
minLength: 2,
placeholder: fallbackInputElement.placeholder,
// TO DO:
// cssNamespace: ??
// displayMenu: 'overlay', this need enable but currently breaks.
confirmOnBlur: false,
onConfirm: (SelectiedContent) => {
window.open('https://www.nhs.uk/search/?q=' + SelectiedContent, '_self');
},
source: getFunnelbackResults,
templates: {
suggestion: suggestionTemplate,
},
};

const accessibleAutocompleteConfig = {
...defaultConfig,
...config,
};

document.getElementById(id).remove();
accessibleAutocomplete(accessibleAutocompleteConfig);
}

export default autocomplete;
2 changes: 2 additions & 0 deletions packages/components/header/template.njk
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<div class="nhsuk-header__search-wrap" id="wrap-search">
<form id="search" class="nhsuk-header__search-form" action="/search/" method="get" role="search">
<label class="nhsuk-u-visually-hidden" for="search-field">Search the NHS website</label>
<div class="autocomplete-container" id="autocomplete-container"></div>
<input class="nhsuk-search__input" id="search-field" placeholder="Search" autocomplete="off" name="search-field" type="search">
<button type="submit" class="nhsuk-search__submit">
<svg class="nhsuk-icon nhsuk-icon__search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
Expand Down Expand Up @@ -113,6 +114,7 @@
<div class="nhsuk-header__search-wrap" id="wrap-search">
<form id="search" class="nhsuk-header__search-form" action="/search/" method="get" role="search">
<label class="nhsuk-u-visually-hidden" for="search-field">Search the NHS website</label>
<div class="autocomplete-container" id="autocomplete-container"></div>
<input class="nhsuk-search__input" id="search-field" placeholder="Search" autocomplete="off" name="search-field" type="search">
<button type="submit" class="nhsuk-search__submit">
<svg class="nhsuk-icon nhsuk-icon__search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
Expand Down
2 changes: 2 additions & 0 deletions packages/nhsuk.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import nhsuk_feedbackBanner from './components/feedback-banner/feedback-banner';
import nhsuk_header from './components/header/header';
import nhsuk_skipLink from './components/skip-link/skip-link';
import autocomplete from './components/header/autocomplete';

// HTML5 polyfills
import './components/details/details.polyfill';
Expand All @@ -11,4 +12,5 @@ document.addEventListener('DOMContentLoaded', function() {
nhsuk_feedbackBanner(3000);
nhsuk_header();
nhsuk_skipLink();
autocomplete();
})

0 comments on commit dfe5f79

Please sign in to comment.