From 7727936c26646714188d6754d504510d057a7173 Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 24 May 2021 17:43:28 -0400 Subject: [PATCH] feat(design): add textarea component --- .../design-land/src/app/app-routing.module.ts | 1 + apps/design-land/src/app/app.component.html | 1 + .../app/text-area/text-area-routing.module.ts | 20 +++++++ .../app/text-area/text-area.component.html | 12 +++++ .../app/text-area/text-area.component.scss | 10 ++++ .../src/app/text-area/text-area.component.ts | 29 ++++++++++ .../src/app/text-area/text-area.module.ts | 29 ++++++++++ .../src/atoms/form/textarea/public_api.ts | 2 + .../form/textarea/textarea.component.scss | 23 ++++++++ .../form/textarea/textarea.component.spec.ts | 46 ++++++++++++++++ .../atoms/form/textarea/textarea.component.ts | 54 +++++++++++++++++++ .../src/atoms/form/textarea/textarea.md | 26 +++++++++ .../atoms/form/textarea/textarea.module.ts | 17 ++++++ libs/design/src/public_api.ts | 1 + 14 files changed, 271 insertions(+) create mode 100644 apps/design-land/src/app/text-area/text-area-routing.module.ts create mode 100644 apps/design-land/src/app/text-area/text-area.component.html create mode 100644 apps/design-land/src/app/text-area/text-area.component.scss create mode 100644 apps/design-land/src/app/text-area/text-area.component.ts create mode 100644 apps/design-land/src/app/text-area/text-area.module.ts create mode 100644 libs/design/src/atoms/form/textarea/public_api.ts create mode 100644 libs/design/src/atoms/form/textarea/textarea.component.scss create mode 100644 libs/design/src/atoms/form/textarea/textarea.component.spec.ts create mode 100644 libs/design/src/atoms/form/textarea/textarea.component.ts create mode 100644 libs/design/src/atoms/form/textarea/textarea.md create mode 100644 libs/design/src/atoms/form/textarea/textarea.module.ts diff --git a/apps/design-land/src/app/app-routing.module.ts b/apps/design-land/src/app/app-routing.module.ts index 6dbac17975..2b602ee971 100644 --- a/apps/design-land/src/app/app-routing.module.ts +++ b/apps/design-land/src/app/app-routing.module.ts @@ -34,6 +34,7 @@ export const appRoutes: Routes = [ { path: 'sidebar', loadChildren: () => import('./sidebar/sidebar.module').then(m => m.SidebarModule) }, { path: 'checkbox', loadChildren: () => import('./checkbox/checkbox.module').then(m => m.CheckboxModule) }, { path: 'radio', loadChildren: () => import('./radio/radio.module').then(m => m.RadioModule) }, + { path: 'text-area', loadChildren: () => import('./text-area/text-area.module').then(m => m.DesignLandTextAreaModule) }, { path: 'typography', loadChildren: () => import('./typography/typography.module').then(m => m.DesignLandTypographyModule) } ] diff --git a/apps/design-land/src/app/app.component.html b/apps/design-land/src/app/app.component.html index e48ea4d22e..c39dc97b22 100644 --- a/apps/design-land/src/app/app.component.html +++ b/apps/design-land/src/app/app.component.html @@ -13,6 +13,7 @@ Image Progress Indicator Radio + Text Area
Molecules
diff --git a/apps/design-land/src/app/text-area/text-area-routing.module.ts b/apps/design-land/src/app/text-area/text-area-routing.module.ts new file mode 100644 index 0000000000..72f8f3562f --- /dev/null +++ b/apps/design-land/src/app/text-area/text-area-routing.module.ts @@ -0,0 +1,20 @@ +import { + Routes, + RouterModule, +} from '@angular/router'; +import { NgModule } from '@angular/core'; +import { DesignLandTextAreaComponent } from './text-area.component'; + +export const formRoutes: Routes = [ + { path: '', component: DesignLandTextAreaComponent }, +]; + +@NgModule({ + imports: [ + RouterModule.forChild(formRoutes), + ], + exports: [ + RouterModule, + ], +}) +export class DesignLandTextAreaRoutingModule {} diff --git a/apps/design-land/src/app/text-area/text-area.component.html b/apps/design-land/src/app/text-area/text-area.component.html new file mode 100644 index 0000000000..6ee1d53500 --- /dev/null +++ b/apps/design-land/src/app/text-area/text-area.component.html @@ -0,0 +1,12 @@ +
+ + + + This is a required field >:( +
+
+ +
+ diff --git a/apps/design-land/src/app/text-area/text-area.component.scss b/apps/design-land/src/app/text-area/text-area.component.scss new file mode 100644 index 0000000000..affa7c8dda --- /dev/null +++ b/apps/design-land/src/app/text-area/text-area.component.scss @@ -0,0 +1,10 @@ +.form { + + & input { + height: 50px; + font-size: 40px; + } + &__error-placeholder { + height: 18px; + } +} \ No newline at end of file diff --git a/apps/design-land/src/app/text-area/text-area.component.ts b/apps/design-land/src/app/text-area/text-area.component.ts new file mode 100644 index 0000000000..5e91a77f39 --- /dev/null +++ b/apps/design-land/src/app/text-area/text-area.component.ts @@ -0,0 +1,29 @@ +import { + Component, + OnInit, +} from '@angular/core'; +import { + FormBuilder, + Validators, + FormGroup, +} from '@angular/forms'; + +@Component({ + selector: 'design-land-text-area', + templateUrl: './text-area.component.html', + styleUrls: ['./text-area.component.scss'], +}) +export class DesignLandTextAreaComponent implements OnInit { + + form: FormGroup; + + constructor( + private fb: FormBuilder, + ) {} + + ngOnInit() { + this.form = this.fb.group({ + textareaExample: ['', Validators.required], + }); + } +} diff --git a/apps/design-land/src/app/text-area/text-area.module.ts b/apps/design-land/src/app/text-area/text-area.module.ts new file mode 100644 index 0000000000..359fff104f --- /dev/null +++ b/apps/design-land/src/app/text-area/text-area.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { DesignLandTextAreaRoutingModule } from './text-area-routing.module'; + +import { DesignLandTextAreaComponent } from './text-area.component'; +import { + DaffTextareaModule, + DaffFormFieldModule, + DaffButtonModule, + DaffInputModule, +} from '@daffodil/design'; +import { ReactiveFormsModule } from '@angular/forms'; + +@NgModule({ + declarations: [ + DesignLandTextAreaComponent, + ], + imports: [ + CommonModule, + DaffTextareaModule, + DaffInputModule, + DaffFormFieldModule, + DesignLandTextAreaRoutingModule, + ReactiveFormsModule, + DaffButtonModule, + ], +}) +export class DesignLandTextAreaModule { } diff --git a/libs/design/src/atoms/form/textarea/public_api.ts b/libs/design/src/atoms/form/textarea/public_api.ts new file mode 100644 index 0000000000..278ca0cf89 --- /dev/null +++ b/libs/design/src/atoms/form/textarea/public_api.ts @@ -0,0 +1,2 @@ +export { DaffTextareaComponent } from './textarea.component'; +export { DaffTextareaModule } from './textarea.module'; diff --git a/libs/design/src/atoms/form/textarea/textarea.component.scss b/libs/design/src/atoms/form/textarea/textarea.component.scss new file mode 100644 index 0000000000..f3b108d1ee --- /dev/null +++ b/libs/design/src/atoms/form/textarea/textarea.component.scss @@ -0,0 +1,23 @@ +@import 'daff-util'; + +:host { + background: transparent; + border: none; + border-radius: 3px; + box-shadow: none; + font-size: 1rem; + line-height: 1.25rem; + margin: 0; + width: 100% !important; /* stylelint-disable-line declaration-no-important */ + box-sizing: border-box; + + &:focus { + border: none; + box-shadow: none; + outline: none; + } + + &::placeholder { + color: transparent; + } +} diff --git a/libs/design/src/atoms/form/textarea/textarea.component.spec.ts b/libs/design/src/atoms/form/textarea/textarea.component.spec.ts new file mode 100644 index 0000000000..1a574208b0 --- /dev/null +++ b/libs/design/src/atoms/form/textarea/textarea.component.spec.ts @@ -0,0 +1,46 @@ +import { + Component, + DebugElement, +} from '@angular/core'; +import { + waitForAsync, + ComponentFixture, + TestBed, +} from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; + +import { DaffTextareaComponent } from './textarea.component'; + + +@Component ({ + template: ``, +}) + +class WrapperComponent {} + +describe('DaffTextareaComponent', () => { + let fixture: ComponentFixture; + let de: DebugElement; + let wrapper: WrapperComponent; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ + DaffTextareaComponent, + WrapperComponent, + ], + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(WrapperComponent); + wrapper = fixture.componentInstance; + de = fixture.debugElement.query(By.css('textarea[daff-textarea]')); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(wrapper).toBeTruthy(); + }); +}); diff --git a/libs/design/src/atoms/form/textarea/textarea.component.ts b/libs/design/src/atoms/form/textarea/textarea.component.ts new file mode 100644 index 0000000000..8ed1de0dfa --- /dev/null +++ b/libs/design/src/atoms/form/textarea/textarea.component.ts @@ -0,0 +1,54 @@ +import { + Component, + Input, + Optional, + Self, + ChangeDetectionStrategy, + HostListener, + ElementRef, +} from '@angular/core'; +import { NgControl } from '@angular/forms'; + +import { DaffFormFieldControl } from '../form-field/form-field-control'; + +/** + * A component for standardizing textarea form fields. + */ +@Component({ + // eslint-disable-next-line @angular-eslint/component-selector + selector: 'textarea[daff-textarea]', + template: '', + styleUrls: ['./textarea.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [ + // eslint-disable-next-line @typescript-eslint/no-use-before-define + { provide: DaffFormFieldControl, useExisting: DaffTextareaComponent }, + ], +}) +export class DaffTextareaComponent implements DaffFormFieldControl { + + focused = false; + + get disabled() { + return this.ngControl.disabled; + } + + /** + * Has the form been submitted. + */ + @Input() formSubmitted: boolean; + + @HostListener('focus') onFocus() { + this.focused = true; + } + + @HostListener('blur') onBlur() { + this.focused = false; + } + + constructor(@Optional() @Self() public ngControl: NgControl, private _elementRef: ElementRef) {} + + focus() { + this._elementRef.nativeElement.focus(); + } +} diff --git a/libs/design/src/atoms/form/textarea/textarea.md b/libs/design/src/atoms/form/textarea/textarea.md new file mode 100644 index 0000000000..23b07b6420 --- /dev/null +++ b/libs/design/src/atoms/form/textarea/textarea.md @@ -0,0 +1,26 @@ +# Textarea +`[daff-textarea]` is a component selector that allows the native ` + This field is required. + + +

Disabled Textarea

+ + + + +``` diff --git a/libs/design/src/atoms/form/textarea/textarea.module.ts b/libs/design/src/atoms/form/textarea/textarea.module.ts new file mode 100644 index 0000000000..d171b31549 --- /dev/null +++ b/libs/design/src/atoms/form/textarea/textarea.module.ts @@ -0,0 +1,17 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; + +import { DaffTextareaComponent } from './textarea.component'; + +@NgModule({ + imports: [ + CommonModule, + ], + exports: [ + DaffTextareaComponent, + ], + declarations: [ + DaffTextareaComponent, + ], +}) +export class DaffTextareaModule {} diff --git a/libs/design/src/public_api.ts b/libs/design/src/public_api.ts index 0aa9bed7ea..237c7762dc 100644 --- a/libs/design/src/public_api.ts +++ b/libs/design/src/public_api.ts @@ -11,6 +11,7 @@ export * from './atoms/image/public_api'; export * from './atoms/form/input/public_api'; export * from './atoms/form/select/public_api'; export * from './atoms/form/checkbox/public_api'; +export * from './atoms/form/textarea/public_api'; export * from './atoms/container/public_api'; export * from './atoms/loading-icon/public_api'; export * from './atoms/progress-indicator/public_api';