Skip to content

Commit

Permalink
Extract editable label as a component
Browse files Browse the repository at this point in the history
  • Loading branch information
rdamazio committed Apr 21, 2024
1 parent ab6381f commit 15639d8
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@if (!editing) {
{{value}}
} @else {
<mat-form-field
appearance="outline"
class="editable-input">
<mat-label>{{label}}</mat-label>
<input
#promptInput
matInput
required
[value]="value">
<button
mat-icon-button
mat-medium-icon-button
matSuffix
class="item-icon"
[attr.aria-label]="'Save changes to ' + label"
(click)="editing = false; value = promptInput.value; onValueChanged();">
<mat-icon fontIcon="save" />
</button>
<button
mat-icon-button
mat-medium-icon-button
matSuffix
class="item-icon"
[attr.aria-label]="'Cancel changes to ' + label"
(click)="editing = false; onCancelled();">
<mat-icon fontIcon="cancel" />
</button>
</mat-form-field>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@use '@angular/material' as mat;

.editable-input {
height: 32px;
@include mat.all-component-densities(-3);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { EditableLabelComponent } from './editable-label.component';

describe('EditableLabelComponent', () => {
let component: EditableLabelComponent;
let fixture: ComponentFixture<EditableLabelComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [EditableLabelComponent]
})
.compileComponents();

fixture = TestBed.createComponent(EditableLabelComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule, MatLabel } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatIconButtonSizesModule } from 'mat-icon-button-sizes';

@Component({
selector: 'editable-label',
standalone: true,
imports: [
MatButtonModule,
MatFormFieldModule,
MatIconButtonSizesModule,
MatIconModule,
MatInputModule,
MatLabel,
],
templateUrl: './editable-label.component.html',
styleUrl: './editable-label.component.scss'
})
export class EditableLabelComponent {
private _value: string = '';

@Output() valueChanged = new EventEmitter<string>();
@Output() cancelled = new EventEmitter<boolean>();
@Output() editing = false;
@Input() label: string = '';

@Input()
get value(): string { return this._value; }
set value(v: string) {
this._value = v;
this.onValueChanged();
}

onValueChanged() {
this.editing = false;
this.valueChanged.emit(this._value);
}

onCancelled() {
this.cancelled.emit(true);
}

edit() {
this.editing = true;
}

cancel() {
this.editing = false;
}
}
56 changes: 19 additions & 37 deletions src/app/checklists/items-list/items-list.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
mat-icon-button
mat-medium-icon-button
class="item-icon"
(click)="editing = true"
(click)="promptInput.edit(); expectationInput.edit()"
[attr.aria-label]="'Edit ' + item.prompt">
<mat-icon fontIcon="edit" />
</button>
Expand Down Expand Up @@ -49,46 +49,28 @@
[class.item-note]="item.type == ChecklistItem_Type.ITEM_NOTE"
[class.item-space]="item.type == ChecklistItem_Type.ITEM_SPACE"
[style.padding-left]="item.indent*25 + 'px'">
@if (!editing) {
{{item.prompt}}
} @else {
<mat-form-field
appearance="outline"
class="prompt-input">
<mat-label>Prompt text</mat-label>
<input
#promptInput
matInput
required
[value]="item.prompt">
<button
mat-icon-button
mat-medium-icon-button
matSuffix
class="item-icon"
[attr.aria-label]="'Save changes to ' + item.prompt"
(click)="item.prompt = promptInput.value; onItemUpdated(); editing = false">
<mat-icon fontIcon="save" />
</button>
<button
mat-icon-button
mat-medium-icon-button
matSuffix
class="item-icon"
[attr.aria-label]="'Cancel changes to ' + item.prompt"
(click)="editing = false">
<mat-icon fontIcon="cancel" />
</button>
</mat-form-field>
}
<!-- TODO: Find a better solution than to save/cancel independent fields together -->
<editable-label
#promptInput
class="prompt-input"
label="Prompt text"
[value]="item.prompt"
(valueChanged)="item.prompt = promptInput.value; onItemUpdated(); expectationInput.cancel();"
(cancelled)="expectationInput.cancel()" />
</span>
@if (item.type === ChecklistItem_Type.ITEM_PROMPT) {
<span [hidden]="item.type !== ChecklistItem_Type.ITEM_PROMPT">
<!-- TODO: Make the dots fill the center space and nothing more -->
<span class="prompt-spacer" *ngIf="!editing">........................</span>
<span class="prompt-spacer" *ngIf="!expectationInput.editing">........................</span>
<span class="prompt-expectation">
{{item.expectation}}
<editable-label
#expectationInput
class="expectation-input"
label="Expectation text"
[value]="item.expectation"
(valueChange)="item.expectation = expectationInput.value; onItemUpdated(); promptInput.cancel();"
(cancelled)="promptInput.cancel()" />
</span>
}
</span>
<div *cdkDragPlaceholder></div>
</div>
}
Expand Down
10 changes: 5 additions & 5 deletions src/app/checklists/items-list/items-list.component.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
@use '@angular/material' as mat;

.container {
margin: 20px;
display: block;
Expand Down Expand Up @@ -72,10 +70,12 @@
color: cyan;
}

.prompt-input {
// TODO: Make this work without ng-deep
::ng-deep .prompt-input mat-form-field {
width: 400px;
}
::ng-deep .prompt-expectation mat-form-field {
width: 300px;
height: 32px;
@include mat.all-component-densities(-3);
}

.item-icon {
Expand Down
6 changes: 2 additions & 4 deletions src/app/checklists/items-list/items-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatIconButtonSizesModule } from 'mat-icon-button-sizes';
import { Checklist, ChecklistItem, ChecklistItem_Type } from '../../../../gen/ts/checklist';
import { EditableLabelComponent } from './editable-label/editable-label.component';

@Component({
selector: 'checklist-items',
Expand All @@ -18,13 +19,10 @@ import { Checklist, ChecklistItem, ChecklistItem_Type } from '../../../../gen/ts
CdkDragHandle,
CdkDragPlaceholder,
CdkDropList,
EditableLabelComponent,
MatButtonModule,
MatFormFieldModule,
MatIconModule,
MatIconButtonSizesModule,
MatIconModule,
MatInputModule,
MatLabel,
NgIf,
]
})
Expand Down

0 comments on commit 15639d8

Please sign in to comment.