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

VOTE-252: state selection list #923

Merged
merged 20 commits into from
Nov 20, 2023
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
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