Last active
February 2, 2018 05:37
-
-
Save vasilionjea/60e1c98f7440233e8c3fe211909a8a10 to your computer and use it in GitHub Desktop.
Ember Accordion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
const { Component, computed } = Ember; | |
export default Component.extend({ | |
tagName: 'button', | |
type: 'button', | |
classNames: ['accordion-item__header'], | |
attributeBindings: ['type', 'aria-expanded', 'aria-controls'], | |
'aria-expanded': computed('isExpanded', function() { | |
return this.get('isExpanded') ? 'true' : 'false'; | |
}), | |
didInsertElement() { | |
const panel = this.element.nextElementSibling; | |
this.set('aria-controls', panel.getAttribute('id')); | |
}, | |
click() { | |
this.get('expand')(); | |
}, | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
const { Component, Object: EmberObject } = Ember; | |
export default Component.extend({ | |
tagName: 'li', | |
classNames: ['accordion-item'], | |
classNameBindings: ['state.isExpanded:accordion-item--is-expanded'], | |
expandOnInit: false, | |
registerState() { | |
const header = this.element.firstElementChild; | |
const state = EmberObject.create({ | |
id: this.elementId, | |
element: this.element, | |
isExpanded: this.get('expandOnInit'), | |
openHeight: this.element.getBoundingClientRect().height, | |
closedHeight: header.getBoundingClientRect().height, | |
}); | |
this.set('state', state); | |
this.get('register')(state); | |
}, | |
didInsertElement() { | |
this.registerState(); | |
if (this.get('expandOnInit')) { | |
this.element.style.maxHeight = `${this.get('state.openHeight')}px`; | |
} else { | |
this.element.style.maxHeight = `${this.get('state.closedHeight')}px`; | |
} | |
}, | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
import KeyboardAccessMixin from 'twiddle/mixins/accordion-keyboard-access'; | |
const { Component, A } = Ember; | |
export default Component.extend(KeyboardAccessMixin, { | |
tagName: 'ul', | |
classNames: ['accordion-list'], | |
_items: A(), | |
actions: { | |
registerItem(item) { | |
item && this.get('_items').pushObject(item); | |
}, | |
expandItem(id) { | |
if (!id) { | |
return; | |
} | |
this.get('_items').forEach(item => { | |
if (item.get('id') === id) { | |
// Show this item | |
item.setProperties({ | |
isExpanded: true, | |
'element.style.maxHeight': `${item.get('openHeight')}px` | |
}); | |
} else { | |
// Hide the rest | |
item.setProperties({ | |
isExpanded: false, | |
'element.style.maxHeight': `${item.get('closedHeight')}px` | |
}); | |
} | |
}); | |
}, | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
const { Component, computed } = Ember; | |
export default Component.extend({ | |
tagName: 'section', | |
classNames: ['accordion-item__panel'], | |
attributeBindings: ['aria-hidden'], | |
'aria-hidden': computed('isExpanded', function() { | |
return this.get('isExpanded') ? 'false' : 'true'; | |
}), | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
const { Controller } = Ember; | |
export default Controller.extend({ | |
appName: 'Ember Accordion', | |
author: { | |
name: 'Billy Onjea', | |
link: 'https://gist.github.com/vasilionjea/60e1c98f7440233e8c3fe211909a8a10' | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { Mixin } = Ember; | |
const KEYCODES = { | |
ARROW_UP: 38, | |
ARROW_DOWN: 40, | |
}; | |
export default Mixin.create({ | |
_onArrowDown(item) { | |
const next = item.nextElementSibling || this.element.firstElementChild; | |
next && next.firstElementChild.focus(); | |
}, | |
_onArrowUp(item) { | |
const prev = item.previousElementSibling || this.element.lastElementChild; | |
prev && prev.firstElementChild.focus(); | |
}, | |
keyDown({ keyCode, target }) { | |
this._super(...arguments); | |
if (!target.classList.contains('accordion-item__header')) { | |
return; | |
} | |
const item = target.parentElement; | |
switch(keyCode) { | |
case KEYCODES.ARROW_DOWN: | |
this._onArrowDown(item); | |
break; | |
case KEYCODES.ARROW_UP: | |
this._onArrowUp(item); | |
break; | |
} | |
}, | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; | |
line-height: 1.5; | |
padding: 0 20px; | |
} | |
h4 { margin: 0; } | |
ul, li { | |
margin: 0; | |
padding: 0; | |
list-style: none; | |
} | |
/** | |
* Accordion Styles | |
*/ | |
.accordion-list { | |
box-sizing: border-box; | |
border: 1px solid #bfbfbf; | |
box-shadow: 0 1px 3px #bfbfbf; | |
} | |
.accordion-item { | |
overflow: hidden; | |
transition: max-height 400ms ease-in-out; | |
} | |
.accordion-item__header { | |
position: relative; | |
display: block; | |
width: 100%; | |
border: none; | |
border-top: 1px solid #bfbfbf; | |
margin: 0; | |
padding: 1em 1.25em; | |
cursor: pointer; | |
font-size: .925rem; | |
font-weight: normal; | |
text-align: left; | |
background: none; | |
border-radius: 0; | |
color: #424242; | |
} | |
.accordion-item:first-child .accordion-item__header { | |
border-top: none; | |
} | |
.accordion-item__header::after { | |
content: ''; | |
display: block; | |
position: absolute; | |
left: 0; | |
bottom: -1px; | |
width: 100%; | |
border-bottom: 1px solid #bfbfbf; | |
} | |
.accordion-item--is-expanded .accordion-item__header, | |
.accordion-item__header:hover, | |
.accordion-item__header:focus { | |
background: #f7f7f7; | |
box-shadow: inset 0 0 3px 2px #f2f2f2; | |
} | |
.accordion-item__panel { | |
visibility: hidden; | |
opacity: 0; | |
transition: visibility 400ms linear, opacity 400ms linear; | |
padding: 1.5em; | |
} | |
.accordion-item--is-expanded .accordion-item__panel { | |
visibility: visible; | |
opacity: 1; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"version": "0.13.0", | |
"EmberENV": { | |
"FEATURES": {} | |
}, | |
"options": { | |
"use_pods": false, | |
"enable-testing": false | |
}, | |
"dependencies": { | |
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js", | |
"ember": "2.16.2", | |
"ember-template-compiler": "2.16.2", | |
"ember-testing": "2.16.2" | |
}, | |
"addons": { | |
"ember-data": "2.16.3" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment