Skip to content
Snippets Groups Projects
Commit 023b7d9c authored by Lukas Haase's avatar Lukas Haase
Browse files

Merge branch '667-refactor-create-composable-components' into 'staging'

Resolve "Refactor - Create composable components"

Closes #667

See merge request arsnova/frag.jetzt!651
parents ae0ddf1f ab384c1c
Branches
Tags
No related merge requests found
Showing
with 370 additions and 5 deletions
......@@ -17,6 +17,20 @@ import { ButtonBaseDirective } from './components/content/menu/ButtonBase.direct
import { MaterialBtnComponent } from './components/style/menu/material-btn/material-btn.component';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { ArsComposeHostDirective } from './compose/ars-compose-host.directive';
import { MatButtonComponent } from './compose/elements/mat-button/mat-button.component';
import { MatToggleComponent } from './compose/elements/mat-toggle/mat-toggle.component';
import { MatChipListComponent } from './compose/elements/mat-chip-list/mat-chip-list.component';
import { MatDatePickerComponent } from './compose/elements/mat-date-picker/mat-date-picker.component';
import { MatMenuItemComponent } from './compose/elements/mat-menu-item/mat-menu-item.component';
import { CommonModule } from '@angular/common';
import { MatChipsModule } from '@angular/material/chips';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { TranslateModule } from '@ngx-translate/core';
import { MatMenuModule } from '@angular/material/menu';
import { MatInputModule } from '@angular/material/input';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
@NgModule({
declarations: [
......@@ -35,13 +49,27 @@ import { MatIconModule } from '@angular/material/icon';
MenuWrapperDirective,
ButtonWrapperDirective,
ButtonBaseDirective,
MaterialBtnComponent
MaterialBtnComponent,
ArsComposeHostDirective,
MatButtonComponent,
MatToggleComponent,
MatChipListComponent,
MatDatePickerComponent,
MatMenuItemComponent
],
imports: [
imports:[
MatIconModule,
MatButtonModule
MatButtonModule,
CommonModule,
MatChipsModule,
MatFormFieldModule,
MatDatepickerModule,
TranslateModule,
MatMenuModule,
MatInputModule,
MatSlideToggleModule
],
exports: [
exports:[
ArsComponent,
FullScreenOverlayComponent,
WrapperDirective,
......@@ -56,7 +84,8 @@ import { MatIconModule } from '@angular/material/icon';
MenuWrapperDirective,
ButtonWrapperDirective,
ButtonBaseDirective,
MaterialBtnComponent
MaterialBtnComponent,
ArsComposeHostDirective
]
})
export class ArsModule { }
// import { ArsComposeHostDirective } from './ars-compose-host.directive';
//
// describe('ArsComposeHostDirective', () => {
// it('should create an instance', () => {
// const directive = new ArsComposeHostDirective();
// expect(directive).toBeTruthy();
// });
// });
import { AfterViewInit, Directive, EventEmitter, Input, Output, ViewContainerRef } from '@angular/core';
@Directive({
selector:'[arsComposeHost]'
})
export class ArsComposeHostDirective implements AfterViewInit{
@Input('ident') ident: any;
@Output() onAfterViewInit: EventEmitter<void> = new EventEmitter<void>();
constructor(
public viewContainerRef: ViewContainerRef
){
}
ngAfterViewInit(){
this.onAfterViewInit.emit();
}
}
import { TranslateService } from '@ngx-translate/core';
import { InjectionToken } from '@angular/core';
export interface ArsMatButtonConfig{
translate: TranslateService;
title: string;
icon?: string;
isSVGIcon?: boolean;
callback?: (e?: MouseEvent) => void;
condition?: () => boolean;
}
export const ARS_MAT_BUTTON_CONFIG = new InjectionToken('ARS_MAT_TOGGLE_DATA');
<button mat-flat-button class="btn" (click)="data.callback($event)">
<ng-container *ngIf="data.icon">
<mat-icon *ngIf="!data.isSVGIcon" style="padding-right:8px;">
{{data.icon}}
</mat-icon>
<mat-icon *ngIf="data.isSVGIcon" [svgIcon]="data.icon" style="padding-right:8px;">
</mat-icon>
</ng-container>
<span>{{data.title}}</span>
</button>
:host{
.btn{
padding:8px;
box-sizing:border-box;
}
}
// import { ComponentFixture, TestBed } from '@angular/core/testing';
//
// import { MatButtonComponent } from './mat-button.component';
//
// describe('MatButtonComponent', () => {
// let component: MatButtonComponent;
// let fixture: ComponentFixture<MatButtonComponent>;
//
// beforeEach(async () => {
// await TestBed.configureTestingModule({
// declarations: [ MatButtonComponent ]
// })
// .compileComponents();
// });
//
// beforeEach(() => {
// fixture = TestBed.createComponent(MatButtonComponent);
// component = fixture.componentInstance;
// fixture.detectChanges();
// });
//
// it('should create', () => {
// expect(component).toBeTruthy();
// });
// });
import { Component, Inject, OnInit } from '@angular/core';
import { ARS_MAT_BUTTON_CONFIG, ArsMatButtonConfig } from './ars-mat-button-config';
@Component({
selector:'ars-mat-button',
templateUrl:'./mat-button.component.html',
styleUrls:['./mat-button.component.scss']
})
export class MatButtonComponent implements OnInit{
constructor(
@Inject(ARS_MAT_BUTTON_CONFIG) public data: ArsMatButtonConfig
){
}
ngOnInit(): void{
}
}
import { InjectionToken } from '@angular/core';
import { ArsObserver } from '../../../models/util/ars-observer';
export interface ArsMatChipConfig{
title: string;
icon?: string;
isSVGIcon?: boolean;
color?: string;
onSelect?: (e: ArsMatChipConfig) => void;
condition?: () => boolean;
}
export interface ArsMatChipListConfig{
list: ArsObserver<ArsMatChipConfig[]>;
def?: string[];
onSelect?: (e: ArsObserver<ArsMatChipConfig[]>) => void;
type?: ArsMatChipListType;
}
export enum ArsMatChipListType{
SELECT,
SELECTION,
TOGGLE
}
export const ARS_MAT_CHIP_LIST_CONFIG = new InjectionToken('ARS_MAT_CHIP_LIST_CONFIG');
<ars-row class="chip-list-wrp">
<mat-chip-list class="chip-list">
<ng-container *ngFor="let chip of data.list.get()">
<mat-chip *ngIf="!chip.condition||chip.condition()" (click)="select(chip)">
<mat-icon *ngIf="chip.icon&&!chip.isSVGIcon" style="padding-right:4px;">{{chip.icon}}</mat-icon>
<mat-icon *ngIf="chip.icon&&chip.isSVGIcon" style="padding-right:4px;" [svgIcon]="chip.icon"></mat-icon>
<span>{{chip.title}}</span>
</mat-chip>
</ng-container>
</mat-chip-list>
</ars-row>
:host {
.chip-list-wrp{
padding:8px;
box-sizing:border-box;
}
.chip-list {
@for $i from 1 through 20 {
:nth-child(#{$i}n) {
animation-delay: #{$i * 0.1 + 0.5}s;
}
}
mat-chip{
animation:fade-bot 1s ease-in-out both;
}
}
@keyframes fade-bot {
0% {
opacity:0;
}
100% {
opacity:1;
}
}
}
// import { ComponentFixture, TestBed } from '@angular/core/testing';
//
// import { MatChipListComponent } from './mat-chip-list.component';
//
// describe('MatChipListComponent', () => {
// let component: MatChipListComponent;
// let fixture: ComponentFixture<MatChipListComponent>;
//
// beforeEach(async () => {
// await TestBed.configureTestingModule({
// declarations: [ MatChipListComponent ]
// })
// .compileComponents();
// });
//
// beforeEach(() => {
// fixture = TestBed.createComponent(MatChipListComponent);
// component = fixture.componentInstance;
// fixture.detectChanges();
// });
//
// it('should create', () => {
// expect(component).toBeTruthy();
// });
// });
import { Component, Inject, OnInit } from '@angular/core';
import { ARS_MAT_CHIP_LIST_CONFIG, ArsMatChipConfig, ArsMatChipListConfig } from './mat-chip-list-config';
import { ArsAnchor } from '../../../models/util/ars-observer';
@Component({
selector:'app-mat-chip-list',
templateUrl:'./mat-chip-list.component.html',
styleUrls:['./mat-chip-list.component.scss']
})
export class MatChipListComponent implements OnInit{
elementAnchor: ArsAnchor<ArsMatChipConfig[]>;
constructor(
@Inject(ARS_MAT_CHIP_LIST_CONFIG) public data: ArsMatChipListConfig
){
}
ngOnInit(): void{
this.elementAnchor = this.data.list.createAnchor();
}
select(chip: ArsMatChipConfig){
chip.onSelect(chip);
if (this.data.onSelect){
this.data.onSelect(this.data.list);
}
}
}
import { InjectionToken } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { MatFormFieldAppearance } from '@angular/material/form-field';
import { ArsObserver } from '../../../models/util/ars-observer';
export interface ArsMatDatePickerConfig{
translate: TranslateService,
appearance?: MatFormFieldAppearance,
title: string,
callback?: (e: Date) => void,
change: ArsObserver<Date>
}
export const ARS_MAT_DATE_PICKER = new InjectionToken('ARS_MAT_DATE_PICKER');
<mat-form-field [appearance]="data.appearance?data.appearance:'fill'" class="ars-mat-date-picker">
<mat-label>{{data.title | translate}}</mat-label>
<input matInput [matDatepicker]="picker" (dateChange)="dateChange($event)">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
:host{
.ars-mat-date-picker{
animation:ars-mat-date-picker-animation 1s ease-in-out both;
box-sizing:border-box;
padding:0px 16px;
width:100%;
}
@keyframes ars-mat-date-picker-animation {
0% {
opacity:0;
}
100% {
opacity:1;
}
}
}
// import { ComponentFixture, TestBed } from '@angular/core/testing';
//
// import { MatDatePickerComponent } from './mat-date-picker.component';
//
// describe('MatDatePickerComponent', () => {
// let component: MatDatePickerComponent;
// let fixture: ComponentFixture<MatDatePickerComponent>;
//
// beforeEach(async () => {
// await TestBed.configureTestingModule({
// declarations: [ MatDatePickerComponent ]
// })
// .compileComponents();
// });
//
// beforeEach(() => {
// fixture = TestBed.createComponent(MatDatePickerComponent);
// component = fixture.componentInstance;
// fixture.detectChanges();
// });
//
// it('should create', () => {
// expect(component).toBeTruthy();
// });
// });
import { Component, Inject, OnInit } from '@angular/core';
import { ARS_MAT_DATE_PICKER, ArsMatDatePickerConfig } from './mat-date-picker-config';
import { MatDatepickerInputEvent } from '@angular/material/datepicker';
@Component({
selector:'ars-mat-date-picker',
templateUrl:'./mat-date-picker.component.html',
styleUrls:['./mat-date-picker.component.scss']
})
export class MatDatePickerComponent implements OnInit{
constructor(
@Inject(ARS_MAT_DATE_PICKER) public data: ArsMatDatePickerConfig
){
}
ngOnInit(): void{
}
dateChange(e: MatDatepickerInputEvent<any>){
console.log(e);
}
}
import { TranslateService } from '@ngx-translate/core';
import { InjectionToken } from '@angular/core';
export interface ArsMatMenuItemConfig{
translate: TranslateService;
icon: string;
isSVGIcon?: boolean;
text: string;
color?: string;
iconColor?: string;
callback?: (e?: MouseEvent) => void;
condition?: () => boolean;
routerLink?: string;
}
export const ARS_MAT_MENU_ITEM_DATA = new InjectionToken('ARS_MAT_MENU_ITEM_DATA');
<button mat-menu-item
tabindex="0"
(click)="action($event)"
*ngIf="data.condition()">
<ng-container *ngIf="data.isSVGIcon">
<mat-icon svgIcon="{{data.icon}}">
</mat-icon>
</ng-container>
<ng-container *ngIf="!data.isSVGIcon">
<mat-icon [ngStyle]="{'color':data.iconColor}">
{{data.icon}}
</mat-icon>
</ng-container>
<span>{{data.text | translate}}</span>
</button>
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment