Skip to content
This repository has been archived by the owner on Aug 15, 2024. It is now read-only.

Commit

Permalink
VOTE-252: update state selection component (#923)
Browse files Browse the repository at this point in the history
  • Loading branch information
mlloydbixal authored Nov 20, 2023
1 parent 21129c2 commit c72c4ab
Show file tree
Hide file tree
Showing 27 changed files with 381 additions and 114 deletions.
1 change: 1 addition & 0 deletions assets/scripts/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ require('../../node_modules/@uswds/uswds/dist/js/uswds.min.js');

// Custom site JS goes here, and is browserify'ed by `gulp script`
require('./external-links');
require('./state-selector');
169 changes: 169 additions & 0 deletions assets/scripts/state-selector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
Dropdown functionality for state selector component.
*/

(() => {
const stateComboBox = document.getElementById("state-combo-box");
const stateInput = document.getElementById("state-input");
const stateDropdownBtn = document.getElementById("state-dropdown-btn");
const stateResultsContainer = document.getElementById("state-results-container");
const stateFilteredOptions = stateComboBox ? stateResultsContainer.getElementsByTagName('a') : null;

// Store dynamic filtered results.
let stateListResults = [];

// Show state dropdown.
function stateListShow() {
stateResultsContainer.removeAttribute('hidden');
}

// Hide state dropdown.
function stateListHide() {
stateResultsContainer.setAttribute('hidden', '');
}

// Toggle state dropdown.
function stateListToggle() {
if (!stateResultsContainer.getAttribute('data-empty')) {
stateResultsContainer.toggleAttribute('hidden');
}
}

// Toggle state dropdown if empty.
function stateListToggleEmpty(empty) {
if (empty) {
stateListHide();
stateResultsContainer.setAttribute('data-empty', true);
} else {
stateListShow();
stateResultsContainer.removeAttribute('data-empty');
}
}

// Filter dropdown results based on user input.
function stateListFilter() {
let filter, txtValue;
filter = stateInput.value.toUpperCase();
txtValue = "";
stateListResults = [];

for (let i = 0; i < stateFilteredOptions.length; i++) {
let li = stateFilteredOptions[i].parentNode;
txtValue = li.textContent || li.innerText;

if (txtValue.toUpperCase().indexOf(filter) > -1) {
li.removeAttribute('hidden');
stateListResults.push(stateFilteredOptions[i]);
} else {
li.setAttribute('hidden', '');
}
}

toggleDataFiltered(filter);
stateListToggleEmpty(!stateListResults.length);
}

// Focus on previous option in dropdown.
function stateListPrevious(option) {
stateListResults.find((element, index) => {
if (element === option) {
if (index === 0) {
stateInput.focus();
}
else {
stateListResults[index - 1].focus();
}
}
});
}

// Focus on next option in dropdown.
function stateListNext(option) {
stateListResults.find((element, index) => {
if (element === option) {
if (index === stateListResults.length - 1) {
stateListResults[0].focus();
}
else {
stateListResults[index + 1].focus();
}
}
});
}

// Toggle data attribute on results container.
function toggleDataFiltered(filter) {
if (filter === '') {
stateResultsContainer.removeAttribute('data-filtered');
}
else {
stateResultsContainer.setAttribute('data-filtered', 'true');
}
}

// Redirect user if value is an exact match to a option.
function quickLinkToState(value) {
stateListResults.find((element) => {
let resultTxt = element.textContent || element.innerText;
if (resultTxt.toUpperCase() === value) {
window.location.href = element.href;
}
});
}

// Initialize event listeners if combobox loaded.
if (stateComboBox) {
// Attach events for combobox component.
stateComboBox.addEventListener('focusout', (e) => {
if (!e.currentTarget.contains(e.relatedTarget)) {
stateListHide();
}
});
stateComboBox.addEventListener('submit', (e) => {
e.preventDefault();
let value = stateInput.value.toUpperCase();
quickLinkToState(value);
})

// Attach events for state input field.
stateInput.addEventListener('focus', stateListShow);
stateInput.addEventListener('keydown', (e) => {
if (e.key === "ArrowDown") {
stateListResults[0].focus();
}
});
stateInput.addEventListener('keyup', (e) => {
if (e.key !== "ArrowDown") {
stateListFilter();
}
});

// Attach events for state links in dropdown.
for (let i = 0; i < stateFilteredOptions.length; i++) {
stateListResults.push(stateFilteredOptions[i]);
stateFilteredOptions[i].addEventListener('keydown', (e) => {
// stateFilteredOptions = stateResultsContainer.getElementsByTagName('a');
if (e.key === "ArrowDown") {
e.preventDefault();
let option = stateFilteredOptions[i];
stateListNext(option);
}
});

stateFilteredOptions[i].addEventListener('keyup', (e) => {
if (e.key === "ArrowUp") {
e.preventDefault();
let option = stateFilteredOptions[i];
stateListPrevious(option);
}
});
}

// Attach events for dropdown toggle button.
stateDropdownBtn.addEventListener('click', (e) => {
e.preventDefault();
stateListToggle();
});
}

})();
4 changes: 2 additions & 2 deletions assets/styles/component/accordion.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
}
}

.usa-accordion__button[aria-expanded=true] {
.usa-accordion__button[aria-expanded="true"] {
background-color: #fff;
color: $deep-blue;
}
Expand Down Expand Up @@ -60,7 +60,7 @@
}

.content-heading {
font-family: Merriweather Web, Georgia, Cambria, Times New Roman, Times, serif;
font-family: "Merriweather Web", Georgia, Cambria, "Times New Roman", Times, serif;
font-weight: normal;
}

Expand Down
4 changes: 1 addition & 3 deletions assets/styles/component/buttons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
text-decoration: none;
}

//"Go back" arrow button and text
// "Go back" arrow button and text
.arrow {
border: solid $color-blue-dark;
border-width: 0 4px 4px 0;
Expand All @@ -32,13 +32,11 @@

.direction {
transform: rotate(135deg);
-webkit-transform: rotate(135deg);
margin-right: 5px;
}

[dir="rtl"] .direction {
transform: rotate(315deg);
-webkit-transform: rotate(315deg);
margin-left: 5px;
}

Expand Down
5 changes: 3 additions & 2 deletions assets/styles/component/hero.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
$arrow-width: 100px;
$arrow-height: 30px;
$arrow-half-width: math.div($arrow-width, 2);

content: "";
position: absolute;
left: calc(50% - #{$arrow-half-width});
bottom: -$arrow-height;
width: 0;
height: 0;
border-style: solid;
border-width: $arrow-height+1 $arrow-half-width 0 $arrow-half-width;
border-width: $arrow-height + 1 $arrow-half-width 0 $arrow-half-width;
border-color: $color-blue transparent transparent transparent;

@include at-media('tablet') {
Expand Down Expand Up @@ -53,7 +54,7 @@

@include at-media('mobile') {
#SiteLogo {
padding: 10px 0 10px;
padding: 10px 0;
}
}

Expand Down
2 changes: 2 additions & 0 deletions assets/styles/component/language-switcher.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
display: flex;
justify-content: flex-end;
padding: 0.5rem 1rem 0.5rem 0;

.usa-button {
a {
color: #fff;
Expand All @@ -22,6 +23,7 @@
columns: 2 auto;
}
}

.usa-language__submenu-item {
padding: 8px;
border: unset;
Expand Down
2 changes: 1 addition & 1 deletion assets/styles/global/typography.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
}

.main-heading {
font-family: Merriweather Web, Georgia, Cambria, Times New Roman, Times, serif;
font-family: "Merriweather Web", Georgia, Cambria, "Times New Roman", Times, serif;

@include at-media-max(tablet-lg) {
span[hidden] {
Expand Down
Loading

0 comments on commit c72c4ab

Please sign in to comment.