Custom Filter Component (#1823)

* Add Accordion component

* Add property to hide icon

* Use accordion component in demo shell

* Add basic doc

* Add adf prefix

* Add element id and change unit test
This commit is contained in:
Maurizio Vitale
2017-04-21 10:26:59 +01:00
committed by Mario Romano
parent 0e4dab8b66
commit 1de625d960
18 changed files with 442 additions and 14 deletions

View File

@@ -0,0 +1,35 @@
.adf-panel-heading {
float: left;
font-size: 14px;
font-weight: bold;
font-style: normal;
font-stretch: normal;
line-height: normal;
letter-spacing: normal;
text-align: left;
color: #000000;
width: 100%;
}
.adf-panel-heading-selected {
color: #448aff;
}
.adf-panel-heading-icon {
float: left;
}
.adf-panel-heading-text {
float: left;
padding-left: 20px;
padding-top: 4px;
}
.adf-panel-heading-toggle {
float: right;
cursor: pointer;
}
.adf-panel-heading-toggle:hover {
opacity: 0.4;
}

View File

@@ -0,0 +1,16 @@
<div class="adf-panel adf-panel-default" [ngClass]="{'adf-panel-open': isOpen}">
<div class="adf-panel-heading" [ngClass]="{'adf-panel-heading-selected': isSelected}">
<div *ngIf="hasHeadingIcon()" class="adf-panel-heading-icon">
<i class="material-icons">{{headingIcon}}</i>
</div>
<div class="adf-panel-heading-text">{{heading}}</div>
<div id="accordion-button" class="adf-panel-heading-toggle" (click)="toggleOpen($event)">
<i class="material-icons">{{getAccordionIcon()}}</i>
</div>
</div>
<div class="adf-panel-collapse" [hidden]="!isOpen">
<div class="adf-panel-body">
<ng-content></ng-content>
</div>
</div>
</div>

View File

@@ -0,0 +1,76 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { AccordionComponent } from './accordion.component';
import { AccordionGroupComponent } from './accordion-group.component';
describe('AccordionGroupComponent', () => {
let fixture: ComponentFixture<AccordionGroupComponent>;
let component: AccordionGroupComponent;
let element: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AccordionGroupComponent
],
providers: [AccordionComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AccordionGroupComponent);
element = fixture.nativeElement;
component = fixture.componentInstance;
});
it('should be closed by default', () => {
component.heading = 'Fake Header';
component.headingIcon = 'fake-icon';
fixture.whenStable().then(() => {
fixture.detectChanges();
let headerToggle = fixture.nativeElement.querySelector('.adf-panel-heading-toggle .material-icons');
expect(headerToggle.innerText).toEqual('expand_more');
let headerText = fixture.nativeElement.querySelector('.adf-panel-heading-text');
expect(headerText.innerText).toEqual('Fake Header');
let headerIcon = fixture.nativeElement.querySelector('.adf-panel-heading-icon .material-icons');
expect(headerIcon.innerText).toEqual('fake-icon');
});
});
it('should be open when click', () => {
component.isSelected = true;
component.heading = 'Fake Header';
component.headingIcon = 'fake-icon';
fixture.detectChanges();
element.querySelector('#accordion-button').click();
fixture.whenStable().then(() => {
fixture.detectChanges();
let headerText = fixture.nativeElement.querySelector('.adf-panel-heading-text');
expect(headerText.innerText).toEqual('Fake Header');
let headerIcon = fixture.nativeElement.querySelector('.adf-panel-heading-icon .material-icons');
expect(headerIcon.innerText).toEqual('fake-icon');
let headerToggle = fixture.nativeElement.querySelector('.adf-panel-heading-toggle .material-icons');
expect(headerToggle.innerText).toEqual('expand_less');
});
});
});

View File

@@ -0,0 +1,79 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component, Input, OnDestroy } from '@angular/core';
import { AccordionComponent } from './accordion.component';
@Component({
selector: 'accordion-group',
moduleId: module.id,
templateUrl: 'accordion-group.component.html',
styleUrls: ['./accordion-group.component.css']
})
export class AccordionGroupComponent implements OnDestroy {
private _isOpen: boolean = false;
private _isSelected: boolean = false;
@Input()
heading: string;
@Input()
headingIcon: string;
@Input()
set isOpen(value: boolean) {
this._isOpen = value;
if (value) {
this.accordion.closeOthers(this);
}
}
get isOpen() {
return this._isOpen;
}
@Input()
set isSelected(value: boolean) {
this._isSelected = value;
}
get isSelected() {
return this._isSelected;
}
constructor(private accordion: AccordionComponent) {
this.accordion.addGroup(this);
}
ngOnDestroy() {
this.accordion.removeGroup(this);
}
hasHeadingIcon() {
return this.headingIcon ? true : false;
}
toggleOpen(event: MouseEvent): void {
event.preventDefault();
this.isOpen = !this.isOpen;
}
getAccordionIcon(): string {
return this.isOpen ? 'expand_less' : 'expand_more';
}
}

View File

@@ -0,0 +1,81 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { AccordionComponent } from './accordion.component';
import { AccordionGroupComponent } from './accordion-group.component';
describe('AccordionComponent', () => {
let fixture: ComponentFixture<AccordionComponent>;
let component: AccordionComponent;
let componentGroup1: AccordionGroupComponent;
let componentGroup2: AccordionGroupComponent;
let componentGroup3: AccordionGroupComponent;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AccordionComponent
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AccordionComponent);
component = fixture.componentInstance;
});
afterEach(() => {
component.groups = [];
});
it('should create the component', () => {
expect(component).toBeTruthy();
});
it('should add the AccordionGroup', () => {
component.addGroup(componentGroup1);
expect(component.groups.length).toBe(1);
});
it('should close all the other group', () => {
componentGroup1 = new AccordionGroupComponent(component);
componentGroup2 = new AccordionGroupComponent(component);
componentGroup3 = new AccordionGroupComponent(component);
componentGroup1.isOpen = false;
componentGroup2.isOpen = true;
componentGroup3.isOpen = false;
expect(component.groups[0].isOpen).toBeFalsy();
expect(component.groups[1].isOpen).toBeTruthy();
expect(component.groups[2].isOpen).toBeFalsy();
componentGroup1.isOpen = true;
expect(component.groups[0].isOpen).toBeTruthy();
expect(component.groups[1].isOpen).toBeFalsy();
expect(component.groups[2].isOpen).toBeFalsy();
});
it('should remove the AccordionGroup', () => {
component.addGroup(componentGroup1);
component.removeGroup(componentGroup1);
expect(component.groups.length).toBe(0);
});
});

View File

@@ -0,0 +1,51 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component } from '@angular/core';
import { AccordionGroupComponent } from './accordion-group.component';
@Component({
selector: 'accordion',
template: `
<ng-content></ng-content>
`,
host: {
'class': 'panel-group'
}
})
export class AccordionComponent {
groups: Array<AccordionGroupComponent> = [];
addGroup(group: AccordionGroupComponent): void {
this.groups.push(group);
}
closeOthers(openGroup: AccordionGroupComponent): void {
this.groups.forEach((group: AccordionGroupComponent) => {
if (group !== openGroup) {
group.isOpen = false;
}
});
}
removeGroup(group: AccordionGroupComponent): void {
const index = this.groups.indexOf(group);
if (index !== -1) {
this.groups.splice(index, 1);
}
}
}

View File

@@ -0,0 +1,24 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {AccordionComponent} from './accordion.component';
import {AccordionGroupComponent} from './accordion-group.component';
export const COLLAPSABLE_DIRECTIVES: [any] = [
AccordionComponent,
AccordionGroupComponent
];

View File

@@ -17,3 +17,4 @@
export * from './context-menu/index';
export * from './material/index';
export * from './collapsable/index';