Skip to content

Commit

Permalink
feat: add disclosure button (resolves #150) (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
greatislander committed Jan 16, 2020
1 parent 828270e commit 76b22c4
Show file tree
Hide file tree
Showing 37 changed files with 215 additions and 162 deletions.
68 changes: 68 additions & 0 deletions src/assets/scripts/Pinecone/DisclosureButton/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* DisclosureButton class.
*/
class DisclosureButton {
/**
* Constructor.
*
* @param {DomNode} label
* @param {Object} options
*/
constructor( label, options ) {
this.label = label;
this.container = this.label.parentNode;
this.config = {
...{
controlSelector: '.disclosure-button',
buttonVariant: false,
visuallyHiddenLabel: false,
},
...options
};
this.initDisclosure();
this.handleClick = this.handleClick.bind( this );
this.addEventListeners();
}

/**
* Initialize content within the disclosure.
*/
initDisclosure() {
const ctrl = document.createElement( 'button' );
const className = ( this.config.buttonVariant ) ?
`button ${this.config.buttonVariant} disclosure-button` :
'button disclosure-button';
const label = this.config.visuallyHiddenLabel ?
`<span class="screen-reader-text">${this.label.textContent}</span>` :
this.label.textContent;
ctrl.setAttribute( 'class', className );
ctrl.setAttribute( 'aria-expanded', 'false' );
ctrl.setAttribute( 'type', 'button' );
ctrl.innerHTML = `
${label}
<svg class="icon icon--chevron-down" viewBox="0 0 20 20" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg"><path id="chevron-down" d="m10 15a1 1 0 0 1 -.71-.29l-5-5a1 1 0 0 1 1.42-1.42l4.29 4.3 4.29-4.3a1 1 0 0 1 1.42 1.42l-5 5a1 1 0 0 1 -.71.29z" fill="currentColor"/></svg>
`;
this.container.insertBefore( ctrl, this.label.nextElementSibling );
this.container.removeChild( this.label );
}

/**
*
* @param {Event} event
*/
handleClick( event ) {
if ( ! event.target.closest( this.config.controlSelector ) ) return;
const ctrl = event.target.closest( this.config.controlSelector );
const expanded = 'true' === ctrl.getAttribute( 'aria-expanded' ) || false;
ctrl.setAttribute( 'aria-expanded', !expanded );
}

/**
* Add click event listeners.
*/
addEventListeners() {
this.container.addEventListener( 'click', this.handleClick, false );
}
}

export default DisclosureButton;
28 changes: 3 additions & 25 deletions src/assets/scripts/Pinecone/NestedCheckbox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class NestedCheckbox {
...options
};

this.initDisclosure();
// this.initDisclosure();
this.initCustomCheckbox();

this.handleChange = this.handleChange.bind( this );
Expand All @@ -35,29 +35,12 @@ class NestedCheckbox {
this.addEventListeners();
}

/**
* Initialize a mixed checkbox.
*/
initDisclosure() {
const disclosureLabel = this.label.nextElementSibling;
const disclosureLabelId = disclosureLabel.id;
const disclosureBtn = document.createElement( 'button' );
disclosureBtn.classList.add( 'disclosure-button' );
disclosureBtn.setAttribute( 'type', 'button' );
disclosureBtn.setAttribute( 'aria-expanded', false );
disclosureBtn.setAttribute( 'aria-labelledby', disclosureLabelId );
disclosureBtn.innerHTML = `
<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" class="icon icon-chevron-down" aria-hidden="true" focusable="false"><path id="chevron-down" d="m10 15a1 1 0 0 1 -.71-.29l-5-5a1 1 0 0 1 1.42-1.42l4.29 4.3 4.29-4.3a1 1 0 0 1 1.42 1.42l-5 5a1 1 0 0 1 -.71.29z" fill="currentColor"></path></svg>
`;
this.input.parentNode.insertBefore( disclosureBtn, this.subGroup );
}

/**
* Initialize a mixed checkbox.
*/
initCustomCheckbox() {
const status = this.getCustomState();
const supplementaryLabel = this.container.querySelector( 'span:not([id])' );
const supplementaryLabel = this.container.querySelector( 'span.supplementary-label' );
supplementaryLabel.parentNode.removeChild( supplementaryLabel );
const customCheckbox = document.createElement( 'div' );
customCheckbox.classList.add( 'checkbox' );
Expand Down Expand Up @@ -132,12 +115,7 @@ class NestedCheckbox {
* @param {Event} event
*/
handleClick( event ) {
if ( ! event.target.closest( this.config.disclosureButtonSelector ) && 'checkbox' !== event.target.getAttribute( 'role' ) ) return;
if ( event.target.closest( this.config.disclosureButtonSelector ) ) {
const ctrl = event.target.closest( this.config.disclosureButtonSelector );
const expanded = 'true' === ctrl.getAttribute( 'aria-expanded' ) || false;
ctrl.setAttribute( 'aria-expanded', !expanded );
}
if ( ! 'checkbox' !== event.target.getAttribute( 'role' ) ) return;
if ( 'checkbox' === event.target.getAttribute( 'role' ) ) {
this.toggleMixedCheckbox( event.target );
}
Expand Down
3 changes: 2 additions & 1 deletion src/assets/scripts/Pinecone/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import Accordion from './Accordion/index.js';
import Card from './Card/index.js';
import DeselectAll from './DeselectAll/index.js';
import DisclosureButton from './DisclosureButton/index.js';
import FilterList from './FilterList/index.js';
import Icon from './Icon/index.js';
import Menu from './Menu/index.js';
import MenuButton from './MenuButton/index.js';
import NestedCheckbox from './NestedCheckbox/index.js';
import Notification from './Notification/index.js';

export default { Accordion, Card, DeselectAll, FilterList, Icon, Menu, MenuButton, NestedCheckbox, Notification };
export default { Accordion, Card, DeselectAll, DisclosureButton, FilterList, Icon, Menu, MenuButton, NestedCheckbox, Notification };
67 changes: 14 additions & 53 deletions src/assets/scripts/pinecone.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,57 +79,18 @@ if ( 0 < resourceActions.length ) {

new Pinecone.Notification();

/**
* Show results.
*/
// const showResults = function() {
// const slugify = require( 'slugify' );
// const resources = document.querySelectorAll( '.card' );
// const checkedFormats = Array.from( document.querySelectorAll( '.input-group.format [type="checkbox"]:checked' ) );
// if ( 0 < checkedFormats.length ) {
// const resourceList = document.querySelector( '.resource-list' );
// const fmts = checkedFormats.map( format => format.value );
// const fmtLabels = checkedFormats.map( format => document.querySelector( `[for="${format.id}"]` ).innerText );
// Array.prototype.forEach.call( resources, resource => {
// if ( fmts.includes( resource.getAttribute( 'data-format' ) ) ) {
// resource.removeAttribute( 'hidden' );
// } else {
// resource.hidden = true;
// }
// } );

// const currentTags = document.querySelector( '.tag-buttons' );
// if ( currentTags ) {
// currentTags.parentNode.removeChild( currentTags );
// }

// const selectedTags = document.createElement( 'ul' );
// selectedTags.className = 'tag-buttons';
// Array.prototype.forEach.call( fmtLabels, label => {
// const li = document.createElement( 'li' );
// li.className = 'tag-button';
// const btn = document.createElement( 'button' );
// btn.className = 'tag-button__button';
// btn.setAttribute( 'data-id', `format-${slugify( label, {lower: true} )}` );
// btn.innerHTML = `
// <span class="screen-reader-text">Remove </span>${label} <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="icon icon-close" aria-hidden="true"><g fill="none" stroke="#203131" stroke-linecap="round" stroke-miterlimit="10" class="stroke" stroke-width="2"><path d="m5 15 10-10"></path><path d="m15 15-10-10"></path></g></svg>
// `;
// li.appendChild( btn );
// selectedTags.appendChild( li );
// } );
// resourceList.insertBefore( selectedTags, resourceList.firstChild );
// } else {
// Array.prototype.forEach.call( resources, resource => {
// resource.removeAttribute( 'hidden' );
// } );

// const currentTags = document.querySelector( '.tag-buttons' );
// if ( currentTags ) {
// currentTags.parentNode.removeChild( currentTags );
// }
// }
// };

// const applyButton = document.getElementById( 'apply-filters' );
// applyButton.addEventListener( 'click', showResults );
const filterDisclosureLabels = document.querySelectorAll( '.filter-disclosure-label' );

if ( filterDisclosureLabels ) {
Array.prototype.forEach.call( filterDisclosureLabels, label => {
new Pinecone.DisclosureButton( label, { buttonVariant: 'button--disc', visuallyHiddenLabel: true } );
} );
}

const disclosureLabels = document.querySelectorAll( '.disclosure-label' );

if ( disclosureLabels ) {
Array.prototype.forEach.call( disclosureLabels, label => {
new Pinecone.DisclosureButton( label );
} );
}
67 changes: 67 additions & 0 deletions src/assets/styles/components/_buttons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,70 @@
outline: none;
}
}

.button--disc {
align-items: center;
background: $blue-50;
border: solid rem(2) transparent;
border-radius: 50%;
color: $blue-500;
display: inline-block;
display: inline-flex;
flex-direction: column;
font-size: rem(16);
height: rem(34);
justify-content: center;
margin: 0;
padding: rem(6) 0;
text-underline-offset: rem(8);
width: rem(34);

svg {
margin-bottom: 0;
}

&:hover {
background: $blue-150;
}

&:active {
background: $blue-100;
color: $blue-500;
}

&:focus {
border-color: $blue-500;
box-shadow:
0 0 0 rem(2) $off-white,
0 0 0 rem(4) $blue-500;
outline: 0;
}
}

.button--disc.button--inverse,
.has-dark-mint-500-background-color .button--disc,
.accordion--filter-list .button-disc {
background: $blue-700;
color: $off-white;

&:hover {
background: $true-black;
}

&:active {
background: $blue-500;
color: $off-white;
}

&:focus {
border-color: $off-white;
box-shadow:
0 0 0 rem(2) $black,
0 0 0 rem(4) $off-white;
}
}

.button--disc:active:focus {
border-color: transparent;
box-shadow: none;
}
61 changes: 0 additions & 61 deletions src/assets/styles/components/_disclosure-button.scss
Original file line number Diff line number Diff line change
@@ -1,76 +1,15 @@
.disclosure-button {
align-items: center;
background: $blue-50;
border: solid rem(2) transparent;
border-radius: 50%;
color: $blue-500;
display: inline-block;
display: inline-flex;
flex-direction: column;
font-size: rem(16);
height: rem(34);
justify-content: center;
margin: 0;
padding: rem(6) 0;
text-underline-offset: rem(8);
width: rem(34);

svg {
margin-bottom: 0;
transition: transform 0.5s;

@media (prefers-reduced-motion: reduce) {
transition: none;
}
}

&:hover {
background: $blue-150;
}

&:active {
background: $blue-100;
color: $blue-500;
}

&:focus {
border-color: $blue-500;
box-shadow:
0 0 0 rem(2) $off-white,
0 0 0 rem(4) $blue-500;
outline: 0;
}

&[aria-expanded="true"] {
svg {
transform: rotate(-180deg);
}
}
}

.has-dark-mint-500-background-color .disclosure-button,
.accordion--filter-list .disclosure-button {
background: $blue-700;
color: $off-white;

&:hover {
background: $true-black;
}

&:active {
background: $blue-500;
color: $off-white;
}

&:focus {
border-color: $off-white;
box-shadow:
0 0 0 rem(2) $black,
0 0 0 rem(4) $off-white;
}
}

.disclosure-button:active:focus {
border-color: transparent;
box-shadow: none;
}
21 changes: 21 additions & 0 deletions src/assets/styles/components/_filter-sort.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,27 @@
background-color: $blue-600;
}
}

.button--disc {
background: $blue-700;
color: $off-white;

&:hover {
background: $true-black;
}

&:active {
background: $blue-500;
color: $off-white;
}

&:focus {
border-color: $off-white;
box-shadow:
0 0 0 rem(2) $black,
0 0 0 rem(4) $off-white;
}
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/assets/styles/components/_icons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@
height: 2.5em;
width: 2.5em;
}

.screen-reader-text + svg {
margin-left: 0;
}

0 comments on commit 76b22c4

Please sign in to comment.