diff --git a/projects/components/src/form-field/form-field.component.scss b/projects/components/src/form-field/form-field.component.scss new file mode 100644 index 000000000..4fb111ad5 --- /dev/null +++ b/projects/components/src/form-field/form-field.component.scss @@ -0,0 +1,34 @@ +@import 'mixins'; + +.form-field { + padding-top: 8px; + + &.optional { + margin-bottom: 18px; + } + + .info-label { + display: flex; + padding-bottom: 4px; + + .label { + @include body-2-medium($gray-7); + display: block; + } + + .optional-label { + @include body-2-regular($gray-4); + padding-left: 4px; + } + + .infobox { + cursor: pointer; + color: $gray-5; + padding-left: 6px; + } + } + + .error-message { + @include footnote($red-6); + } +} diff --git a/projects/components/src/form-field/form-field.component.test.ts b/projects/components/src/form-field/form-field.component.test.ts new file mode 100644 index 000000000..87f155abe --- /dev/null +++ b/projects/components/src/form-field/form-field.component.test.ts @@ -0,0 +1,57 @@ +import { IconType } from '@hypertrace/assets-library'; +import { createHostFactory } from '@ngneat/spectator/jest'; +import { MockComponent, MockModule } from 'ng-mocks'; +import { IconComponent } from '../icon/icon.component'; +import { LabelComponent } from '../label/label.component'; +import { TooltipModule } from '../tooltip/tooltip.module'; +import { FormFieldComponent } from './form-field.component'; + +describe('Form Field Component', () => { + const hostFactory = createHostFactory({ + component: FormFieldComponent, + declarations: [MockComponent(LabelComponent), MockComponent(IconComponent)], + imports: [MockModule(TooltipModule)], + shallow: true + }); + + test('should show mandatory form field data', () => { + const spectator = hostFactory( + ` + + `, + { + hostProps: { + label: 'Label', + icon: IconType.Info, + iconTooltip: 'Add or update a text', + errorLabel: 'Error message' + } + } + ); + const labels = spectator.queryAll(LabelComponent); + expect(labels[0].label).toEqual('Label'); + expect(labels[1].label).toEqual('Error message'); + + const icon = spectator.query(IconComponent); + expect(icon?.icon).toEqual(IconType.Info); + }); + + test('should show optional form field data', () => { + const spectator = hostFactory( + ` + + `, + { + hostProps: { + label: 'Label', + icon: IconType.Info, + iconTooltip: 'Add or update a text', + isOptional: true + } + } + ); + const labels = spectator.queryAll(LabelComponent); + expect(labels[0].label).toEqual('Label'); + expect(labels[1].label).toEqual('(Optional)'); + }); +}); diff --git a/projects/components/src/form-field/form-field.component.ts b/projects/components/src/form-field/form-field.component.ts new file mode 100644 index 000000000..1b33d37a7 --- /dev/null +++ b/projects/components/src/form-field/form-field.component.ts @@ -0,0 +1,44 @@ +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { IconSize } from '../icon/icon-size'; + +@Component({ + selector: 'ht-form-field', + styleUrls: ['./form-field.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +
+
+ + + +
+ + +
+ ` +}) +export class FormFieldComponent { + @Input() + public label?: string; + + @Input() + public isOptional?: boolean = false; + + @Input() + public icon?: string; + + @Input() + public iconSize?: IconSize = IconSize.Small; + + @Input() + public iconTooltip?: string; + + @Input() + public errorLabel?: string = ''; +} diff --git a/projects/components/src/form-field/form-field.module.ts b/projects/components/src/form-field/form-field.module.ts new file mode 100644 index 000000000..847f6910d --- /dev/null +++ b/projects/components/src/form-field/form-field.module.ts @@ -0,0 +1,13 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { IconModule } from '../icon/icon.module'; +import { LabelModule } from '../label/label.module'; +import { TooltipModule } from '../tooltip/tooltip.module'; +import { FormFieldComponent } from './form-field.component'; + +@NgModule({ + imports: [CommonModule, LabelModule, IconModule, TooltipModule], + declarations: [FormFieldComponent], + exports: [FormFieldComponent] +}) +export class FormFieldModule {} diff --git a/projects/components/src/public-api.ts b/projects/components/src/public-api.ts index 2ac3df788..280fcb179 100644 --- a/projects/components/src/public-api.ts +++ b/projects/components/src/public-api.ts @@ -104,6 +104,10 @@ export * from './filtering/filter-modal/in-filter-modal.component'; // Filter Parser export * from './filtering/filter/parser/filter-parser-lookup.service'; +// Form Section +export * from './form-field/form-field.component'; +export * from './form-field/form-field.module'; + // Greeting label export { GreetingLabelModule } from './greeting-label/greeting-label.module'; export { GreetingLabelComponent } from './greeting-label/greeting-label.component';