UNPKG

v-accordion

Version:

vAccordion - AngularJS multi-level accordion component

9 lines (8 loc) 8.18 kB
/** * vAccordion - AngularJS multi-level accordion component * @version v1.6.0 * @link http://lukaszwatroba.github.io/v-accordion * @author Łukasz Wątroba <l@lukaszwatroba.com> * @license MIT License, http://www.opensource.org/licenses/MIT */ !function(e){"use strict";function n(n){return{restrict:"E",transclude:!0,controller:a,scope:{control:"=?",expandCb:"&?onexpand",collapseCb:"&?oncollapse",id:"@?"},link:{pre:function(n,a,i){n.allowMultiple=e.isDefined(i.multiple)&&(""===i.multiple||"true"===i.multiple)},post:function(a,i,t,o,d){function r(){var n=["toggle","expand","collapse","expandAll","collapseAll","hasExpandedPane"];e.forEach(n,function(e){if(a.control[e])throw new Error("The `"+e+"` method can not be overwritten")})}if(d(a.$parent.$new(),function(e,n){n.$accordion=a.internalControl,a.id&&(n.$accordion.id=a.id),i.append(e)}),t.$set("role","tablist"),a.allowMultiple&&t.$set("aria-multiselectable","true"),e.isDefined(a.control)){r();var c=e.extend({},a.internalControl,a.control);a.control=a.internalControl=c}else a.control=a.internalControl;n(function(){var n=e.isDefined(o.getAccordionId())?o.getAccordionId()+":onReady":"vAccordion:onReady";a.$emit(n)},0)}}}}function a(n){var a=this,i=!1;n.panes=[],n.expandCb=e.isFunction(n.expandCb)?n.expandCb:e.noop,n.collapseCb=e.isFunction(n.collapseCb)?n.collapseCb:e.noop,a.hasExpandedPane=function(){for(var e=!1,a=0,i=n.panes.length;i>a;a++){var t=n.panes[a];if(t.isExpanded){e=!0;break}}return e},a.getPaneByIndex=function(a){var i;return e.forEach(n.panes,function(n){n.$parent&&e.isDefined(n.$parent.$index)&&n.$parent.$index===a&&(i=n)}),i?i:n.panes[a]},a.getPaneIndex=function(a){var i;return e.forEach(n.panes,function(n){n.$parent&&e.isDefined(n.$parent.$index)&&n===a&&(i=n.$parent.$index)}),e.isDefined(i)?i:n.panes.indexOf(a)},a.getPaneById=function(a){var i;return e.forEach(n.panes,function(e){e.id&&e.id===a&&(i=e)}),i},a.getPaneId=function(e){return e.id},a.getAccordionId=function(){return n.id},a.disable=function(){i=!0},a.enable=function(){i=!1},a.addPane=function(e){if(!n.allowMultiple&&a.hasExpandedPane()&&e.isExpanded)throw new Error("The `multiple` attribute can't be found");n.panes.push(e),e.isExpanded&&n.expandCb({index:a.getPaneIndex(e),id:e.id,pane:e})},a.focusNext=function(){for(var e=n.panes.length,a=0;e>a;a++){var i=n.panes[a];if(i.isFocused){var t=a+1;t>n.panes.length-1&&(t=0);var o=n.panes[t];o.paneElement.find("v-pane-header")[0].focus();break}}},a.focusPrevious=function(){for(var e=n.panes.length,a=0;e>a;a++){var i=n.panes[a];if(i.isFocused){var t=a-1;0>t&&(t=n.panes.length-1);var o=n.panes[t];o.paneElement.find("v-pane-header")[0].focus();break}}},a.toggle=function(e){!i&&e&&(n.allowMultiple||a.collapseAll(e),e.isExpanded=!e.isExpanded,e.isExpanded?n.expandCb({index:a.getPaneIndex(e),id:e.id,pane:e}):n.collapseCb({index:a.getPaneIndex(e),id:e.id,pane:e}))},a.expand=function(e){!i&&e&&(n.allowMultiple||a.collapseAll(e),e.isExpanded||(e.isExpanded=!0,n.expandCb({index:a.getPaneIndex(e),id:e.id,pane:e})))},a.collapse=function(e){!i&&e&&e.isExpanded&&(e.isExpanded=!1,n.collapseCb({index:a.getPaneIndex(e),id:e.id,pane:e}))},a.expandAll=function(){if(!i){if(!n.allowMultiple)throw new Error("The `multiple` attribute can't be found");e.forEach(n.panes,function(e){a.expand(e)})}},a.collapseAll=function(t){i||e.forEach(n.panes,function(e){e!==t&&a.collapse(e)})},n.internalControl={toggle:function(n){e.isString(n)?a.toggle(a.getPaneById(n)):a.toggle(a.getPaneByIndex(n))},expand:function(n){e.isString(n)?a.expand(a.getPaneById(n)):a.expand(a.getPaneByIndex(n))},collapse:function(n){e.isString(n)?a.collapse(a.getPaneById(n)):a.collapse(a.getPaneByIndex(n))},expandAll:a.expandAll,collapseAll:a.collapseAll,hasExpandedPane:a.hasExpandedPane}}function i(n,a,i){return{restrict:"E",require:"^vAccordion",transclude:!0,controller:t,scope:{isExpanded:"=?expanded",isDisabled:"=?ngDisabled",id:"@?"},link:function(n,t,o,d,r){function c(a){a=e.isDefined(v)?v+":"+a:"vAccordion:"+a,n.$emit(a)}function l(){d.disable(),f.attr("aria-hidden","false"),u.attr({"aria-selected":"true","aria-expanded":"true"}),c("onExpand"),a.addClass(t,p.expanded).then(function(){d.enable(),c("onExpandAnimationEnd")})}function s(){d.disable(),f.attr("aria-hidden","true"),u.attr({"aria-selected":"false","aria-expanded":"false"}),c("onCollapse"),a.removeClass(t,p.expanded).then(function(){d.enable(),c("onCollapseAnimationEnd")})}r(n.$parent.$new(),function(e,a){a.$pane=n.internalControl,n.id&&(a.$pane.id=n.id),t.append(e)}),e.isDefined(n.isExpanded)||(n.isExpanded=e.isDefined(o.expanded)&&""===o.expanded),e.isDefined(o.disabled)&&(n.isDisabled=!0);var p=i.states,u=t.find("v-pane-header"),f=t.find("v-pane-content"),x=f.find("div"),v=d.getAccordionId();if(!u[0])throw new Error("The `v-pane-header` directive can't be found");if(!f[0])throw new Error("The `v-pane-content` directive can't be found");n.paneElement=t,n.paneContentElement=f,n.paneInnerElement=x,n.accordionCtrl=d,d.addPane(n),n.$evalAsync(function(){n.isExpanded?(t.addClass(p.expanded),f.css("max-height","none").attr("aria-hidden","false"),u.attr({"aria-selected":"true","aria-expanded":"true"})):(f.css("max-height","0px").attr("aria-hidden","true"),u.attr({"aria-selected":"false","aria-expanded":"false"}))}),n.$watch("isExpanded",function(e,n){return e===n?!0:(e?l():s(),void 0)})}}}function t(e){var n=this;n.isExpanded=function(){return e.isExpanded},n.toggle=function(){e.isAnimating||e.isDisabled||e.accordionCtrl.toggle(e)},n.expand=function(){e.isAnimating||e.isDisabled||e.accordionCtrl.expand(e)},n.collapse=function(){e.isAnimating||e.isDisabled||e.accordionCtrl.collapse(e)},n.focusPane=function(){e.isFocused=!0},n.blurPane=function(){e.isFocused=!1},e.internalControl={toggle:n.toggle,expand:n.expand,collapse:n.collapse,isExpanded:n.isExpanded}}function o(){return{restrict:"E",require:"^vPane",transclude:!0,template:"<div ng-transclude></div>",scope:{},link:function(e,n,a){a.$set("role","tabpanel"),a.$set("aria-hidden","true")}}}function d(){return{restrict:"E",require:["^vPane","^vAccordion"],transclude:!0,template:"<div ng-transclude></div>",scope:{},link:function(n,a,i,t){function o(){return p?!1:(n.$apply(function(){l.toggle()}),void 0)}function d(e){32===e.keyCode||13===e.keyCode?(n.$apply(function(){l.toggle()}),e.preventDefault()):39===e.keyCode||40===e.keyCode?(n.$apply(function(){s.focusNext()}),e.preventDefault()):(37===e.keyCode||38===e.keyCode)&&(n.$apply(function(){s.focusPrevious()}),e.preventDefault())}function r(){l.focusPane()}function c(){l.blurPane()}i.$set("role","tab"),i.$set("tabindex","0");var l=t[0],s=t[1],p=e.isDefined(i.inactive);a[0].onfocus=r,a[0].onblur=c,a.bind("click",o),a.bind("keydown",d),n.$on("$destroy",function(){a.unbind("click",o),a.unbind("keydown",d),a[0].onfocus=null,a[0].onblur=null})}}}e.module("vAccordion.config",[]).constant("accordionConfig",{states:{expanded:"is-expanded"},expandAnimationDuration:.5}).animation(".is-expanded",["$animateCss","accordionConfig",function(n,a){return{addClass:function(i,t,o){var d=e.element(i[0].querySelector("v-pane-content")),r=e.element(d[0].querySelector("div")),c=r[0].offsetHeight,l=n(d,{easing:"ease",from:{maxHeight:"0px"},to:{maxHeight:c+"px"},duration:a.expandAnimationDuration});return l.start().done(function(){d.css("max-height","none"),o()}),function(e){e&&d.css("max-height","none")}},removeClass:function(i,t,o){var d=e.element(i[0].querySelector("v-pane-content")),r=e.element(d[0].querySelector("div")),c=r[0].offsetHeight,l=n(d,{easing:"ease",from:{maxHeight:c+"px"},to:{maxHeight:"0px"},duration:a.expandAnimationDuration});return l.start().done(o),function(e){e&&d.css("max-height","0px")}}}}]),e.module("vAccordion.directives",[]),e.module("vAccordion",["vAccordion.config","vAccordion.directives"]),e.module("vAccordion.directives").directive("vAccordion",n),n.$inject=["$timeout"],a.$inject=["$scope"],e.module("vAccordion.directives").directive("vPane",i),i.$inject=["$timeout","$animate","accordionConfig"],t.$inject=["$scope"],e.module("vAccordion.directives").directive("vPaneContent",o),e.module("vAccordion.directives").directive("vPaneHeader",d)}(angular);