Skip to content

Instantly share code, notes, and snippets.

@swati16
Created July 15, 2020 12:28
Show Gist options
  • Save swati16/bc7cde8cc4170c873a1a14c7d5f2f18b to your computer and use it in GitHub Desktop.
Save swati16/bc7cde8cc4170c873a1a14c7d5f2f18b to your computer and use it in GitHub Desktop.
vAccordion
<div class="u-wideWrapper u-paddingHm u-paddingTl" ng-app="myApp" ng-controller="MainController">
<header class="u-marginBl u-textCenter">
<div>
<svg class="u-inlineBlock" width="58px" height="58px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 54"><g><path fill="#4CAF50" d="M3.1,27.9c0,0,10.2-24.1,11.6-27.2c0.2-0.5,0.6-0.8,1.2-0.6c0.5,0.1,0.8,0.7,1.5,2.2c1.3,2.9,18,37.2,18.7,38.6c0.8,1.6,1,2.6,0.7,3.4c-0.3,0.6-1,1.1-1.8,1.4c-2.3,0.9-20.3,7.8-21.5,8.3c-0.7,0.3-0.8-0.4-1.4-1.7C11.6,51,3.7,32.1,3.1,30.7C2.5,29.3,3.1,27.9,3.1,27.9z"/><path fill="#2196F3" d="M50.9,17.3c-0.3-0.3-0.4-0.4-0.7-0.2c-0.3,0.1-11.5,8.6-16.8,12.5c2.7,5.5,4.7,9.7,5,10.2c0.4,0.8,0.8,1.7,1,2.6c0.1-0.2,0.2-0.3,0.3-0.5c0.9-1.8,11.3-23.4,11.5-23.8C51.3,17.7,51.2,17.7,50.9,17.3z"/></g></svg>
<h2 class="u-marginTs">vAccordion</h2>
</div>
<h5 class="u-marginBl">AngularJS multi-level accordion component.</h5>
<hr>
</header>
<div class="Grid Grid--gutters md-Grid--2col">
<div class="Grid-cell u-marginBl">
<h4 class="u-marginVm">Works with (or without) ng-repeat</h4>
<v-accordion id="accordionA" class="vAccordion--default" control="accordionA" onexpand="expandCallback(index, id)" oncollapse="collapseCallback(index, id)">
<v-pane id="{{ ::pane.id }}" ng-repeat="pane in panesA" expanded="pane.isExpanded">
<v-pane-header id="{{ ::pane.id }}-header" aria-controls="{{ ::pane.id }}-content">
<h5>{{ ::pane.header }}</h5>
</v-pane-header>
<v-pane-content id="{{ ::pane.id }}-content" aria-labelledby="{{ ::pane.id }}-header">
<p>{{ ::pane.content }}</p>
<v-accordion id="nestedAccordionA" ng-if="pane.subpanes">
<v-pane id="{{ ::subpane.id }}" ng-repeat="subpane in pane.subpanes" ng-disabled="subpane.isDisabled">
<v-pane-header id="{{ ::subpane.id }}-header" aria-controls="{{ ::subpane.id }}-header">
<h5>{{ ::subpane.header }}</h5>
</v-pane-header>
<v-pane-content id="{{ ::subpane.id }}-content" aria-labelledby="{{ ::subpane.id }}-content">
<p>{{ ::subpane.content }}</p>
</v-pane-content>
</v-pane>
</v-accordion>
</v-pane-content>
</v-pane>
</v-accordion>
<div class="ButtonGroup ButtonGroup--hz ButtonGroup--collapse u-marginVm">
<div class="ButtonGroup-item">
<button class="Button Button--default" ng-click="accordionA.toggle(panesA[0].id)">Toogle first</button>
</div>
<div class="ButtonGroup-item">
<button class="Button Button--default" ng-click="accordionA.toggle(panesA[2].id)">Toogle last</button>
</div>
</div>
</div>
<div class="Grid-cell u-marginBl">
<h4 class="u-marginVm">Allows multiple sections open at once</h4>
<v-accordion id="accordionB" class="vAccordion--default" multiple control="accordionB">
<v-pane id="{{ ::pane.id }}" ng-repeat="pane in panesB" expanded="pane.isExpanded">
<v-pane-header id="{{ ::pane.id }}-header" aria-controls="{{ ::pane.id }}-header">
<h5>{{ ::pane.header }}</h5>
</v-pane-header>
<v-pane-content id="{{ ::pane.id }}-content" aria-labelledby="{{ ::pane.id }}-content">
<p>{{ ::pane.content }}</p>
<v-accordion id="nestedAccordionB" multiple ng-if="pane.subpanes">
<v-pane id="{{ ::subpane.id }}" ng-repeat="subpane in pane.subpanes" ng-disabled="subpane.isDisabled">
<v-pane-header id="{{ ::subpane.id }}-header" aria-controls="{{ ::subpane.id }}-header">
<h5>{{ ::subpane.header }}</h5>
</v-pane-header>
<v-pane-content id="{{ ::subpane.id }}-content" aria-labelledby="{{ ::subpane.id }}-content">
<p>{{ ::subpane.content }}</p>
</v-pane-content>
</v-pane>
</v-accordion>
</v-pane-content>
</v-pane>
</v-accordion>
<div class="ButtonGroup ButtonGroup--hz ButtonGroup--collapse u-marginVm">
<div class="ButtonGroup-item">
<button class="Button Button--default" ng-click="accordionB.expandAll()">Expand all</button>
</div>
<div class="ButtonGroup-item">
<button class="Button Button--default" ng-click="accordionB.collapseAll()">Collapse all</button>
</div>
</div>
</div>
</div>
<hr>
<footer class="u-cf u-paddingBl">
<div class="u-textCenter">
<a href="https://github.com/LukaszWatroba" class="u-inlineBlock u-linkClean">
<svg width="28px" height="28px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 54"><g><path fill="#2196F3" d="M3.1,27.9c0,0,10.2-24.1,11.6-27.2c0.2-0.5,0.6-0.8,1.2-0.6c0.5,0.1,0.8,0.7,1.5,2.2c1.3,2.9,18,37.2,18.7,38.6c0.8,1.6,1,2.6,0.7,3.4c-0.3,0.6-1,1.1-1.8,1.4c-2.3,0.9-20.3,7.8-21.5,8.3c-0.7,0.3-0.8-0.4-1.4-1.7C11.6,51,3.7,32.1,3.1,30.7C2.5,29.3,3.1,27.9,3.1,27.9z"/><path fill="#2196F3" d="M50.9,17.3c-0.3-0.3-0.4-0.4-0.7-0.2c-0.3,0.1-11.5,8.6-16.8,12.5c2.7,5.5,4.7,9.7,5,10.2c0.4,0.8,0.8,1.7,1,2.6c0.1-0.2,0.2-0.3,0.3-0.5c0.9-1.8,11.3-23.4,11.5-23.8C51.3,17.7,51.2,17.7,50.9,17.3z"/></g></svg>
<br>
<small>
By Łukasz Wątroba
</small>
</a>
</div>
</footer>
</div>
<!-- Fork me on GitHub ribbon -->
<a href="https://github.com/LukaszWatroba/v-accordion"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a>
(function (angular) {
'use strict';
angular
.module('myApp', [ 'ngAnimate', 'vAccordion' ])
.controller('MainController', function ($scope) {
$scope.panesA = [
{
id: 'pane-1a',
header: 'Pane 1',
content: 'Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. Nulla imperdiet sit amet magna. Vestibulum dapibus, mauris nec malesuada fames ac turpis velit, rhoncus eu, luctus et interdum adipiscing wisi.',
isExpanded: true
},
{
id: 'pane-2a',
header: 'Pane 2',
content: 'Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies.'
},
{
id: 'pane-3a',
header: 'Pane 3',
content: 'Aliquam erat ac ipsum. Integer aliquam purus. Quisque lorem tortor fringilla sed, vestibulum id, eleifend justo vel bibendum sapien massa ac turpis faucibus orci luctus non.',
subpanes: [
{
id: 'subpane-1a',
header: 'Subpane 1',
content: 'Quisque lorem tortor fringilla sed, vestibulum id, eleifend justo vel bibendum sapien massa ac turpis faucibus orci luctus non.'
},
{
id: 'subpane-2a',
header: 'Subpane 2 (disabled)',
content: 'Curabitur et ligula. Ut molestie a, ultricies porta urna. Quisque lorem tortor fringilla sed, vestibulum id.',
isDisabled: true
}
]
}
];
$scope.panesB = [
{
id: 'pane-1b',
header: 'Pane 1',
content: 'Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. Nulla imperdiet sit amet magna. Vestibulum dapibus, mauris nec malesuada fames ac turpis velit, rhoncus eu, luctus et interdum adipiscing wisi.',
isExpanded: true
},
{
id: 'pane-2b',
header: 'Pane 2',
content: 'Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies.'
},
{
id: 'pane-3b',
header: 'Pane 3',
content: 'Aliquam erat ac ipsum. Integer aliquam purus. Quisque lorem tortor fringilla sed, vestibulum id, eleifend justo vel bibendum sapien massa ac turpis faucibus orci luctus non.',
subpanes: [
{
id: 'subpane-1b',
header: 'Subpane 1',
content: 'Quisque lorem tortor fringilla sed, vestibulum id, eleifend justo vel bibendum sapien massa ac turpis faucibus orci luctus non.'
},
{
id: 'subpane-2b',
header: 'Subpane 2 (disabled)',
content: 'Curabitur et ligula. Ut molestie a, ultricies porta urna. Quisque lorem tortor fringilla sed, vestibulum id.',
isDisabled: true
}
]
}
];
$scope.expandCallback = function (index, id) {
console.log('expand:', index, id);
};
$scope.collapseCallback = function (index, id) {
console.log('collapse:', index, id);
};
$scope.$on('accordionA:onReady', function () {
console.log('accordionA is ready!');
});
});
})(angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.min.js"></script>
<script src="https://lukaszwatroba.github.io/v-accordion/dist/v-accordion.js"></script>
// -------------------------------------
// Settings
// -------------------------------------
$v-accordion-default-theme: true !default;
// Accordion
// -------------------------------------
$v-accordion-spacing: 20px !default;
$v-pane-border-color: #D8D8D8 !default;
$v-pane-expanded-border-color: #2196F3 !default;
$v-pane-icon-color: #2196F3 !default;
$v-pane-hover-color: #2196F3 !default;
$v-pane-disabled-opacity: 0.6 !default;
$v-pane-expand-animation-duration: 0.5s !default;
$v-pane-hover-animation-duration: 0.25s !default;
/* Base styles
***************************************/
v-accordion {
display: block;
}
v-pane {
display: block;
&.is-expanded {
> v-pane-content {
> div {
display: visible;
}
}
}
&[disabled] > v-pane-header {
opacity: $v-pane-disabled-opacity;
pointer-events: none;
}
}
v-pane-header {
display: block;
position: relative;
cursor: pointer;
user-select: none;
outline: none;
&:focus {
outline: none;
}
> div {
display: block;
}
}
v-pane-content {
display: block;
position: relative;
overflow: hidden;
max-height: 0px;
> div {
visibility: none;
}
}
@if $v-accordion-default-theme {
/* Theme: default
***************************************/
.vAccordion--default {
v-accordion {
margin-top: $v-accordion-spacing;
padding-left: $v-accordion-spacing;
}
v-pane-content {
> div {
padding-bottom: $v-accordion-spacing;
opacity: 0;
transform: translate3d(0, 30px, 0);
transition: all $v-pane-expand-animation-duration;
}
}
v-pane {
overflow: hidden;
&.is-expanded {
> v-pane-header {
border-bottom-color: $v-pane-expanded-border-color;
&::after {
transform: rotate(90deg);
opacity: 0;
}
&::before {
transform: rotate(0deg);
}
}
> v-pane-content > div {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
&[disabled] v-pane-header {
&::after,
&::before {
display: none;
}
}
}
v-pane-header {
padding: 5px 0;
margin-bottom: $v-accordion-spacing;
border-bottom: 2px solid $v-pane-border-color;
transition: all $v-pane-hover-animation-duration;
&::after,
&::before {
content: '';
display: block;
position: absolute;
top: 50%;
right: 0;
width: 10px;
height: 1px;
background-color: $v-pane-icon-color;
transform-origin: 50% 50%;
will-change: transform;
transition: all $v-pane-hover-animation-duration;
}
&::before {
transform: rotate(-90deg);
}
&:hover,
&:focus {
color: $v-pane-hover-color;
}
}
}
}
<link href="https://lukaszwatroba.github.io/valitycss/dist/vality.min.css" rel="stylesheet" />

vAccordion

AngularJS multi-level accordion.

  • Allows for a nested structure
  • Works with (or without) ng-repeat
  • Allows multiple sections to be open at once

A Pen by Łukasz Wątroba on CodePen.

License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment