diff --git a/apps/design-land/src/app/input/input.component.html b/apps/design-land/src/app/input/input.component.html index 9f30c8d256..09ba796c7f 100644 --- a/apps/design-land/src/app/input/input.component.html +++ b/apps/design-land/src/app/input/input.component.html @@ -18,7 +18,17 @@

Disabled

+

Input With Hint

+

The input in this example has a hint.

+ + +

With Reactive Forms

The input in this example uses the ReactiveFormsModule to display errors.

- \ No newline at end of file + + +

Password With Reactive Forms

+

This is a special case where hints and errors for passwords are displayed.

+ + diff --git a/libs/design/input/examples/src/examples.ts b/libs/design/input/examples/src/examples.ts index acee588cb3..22a5c662c4 100644 --- a/libs/design/input/examples/src/examples.ts +++ b/libs/design/input/examples/src/examples.ts @@ -1,11 +1,15 @@ import { BasicInputComponent } from './basic-input/basic-input.component'; import { InputDisabledComponent } from './input-disabled/input-disabled.component'; import { InputErrorComponent } from './input-error/input-error.component'; +import { InputHintComponent } from './input-hint/input-hint.component'; import { InputWithFormFieldComponent } from './input-with-form-field/input-with-form-field.component'; +import { PasswordWithFormFieldComponent } from './password-with-form-field/password-with-form-field.component'; export const INPUT_EXAMPLES = [ BasicInputComponent, InputWithFormFieldComponent, InputDisabledComponent, InputErrorComponent, + PasswordWithFormFieldComponent, + InputHintComponent, ]; diff --git a/libs/design/input/examples/src/input-error/input-error.component.html b/libs/design/input/examples/src/input-error/input-error.component.html index f052626424..47143b6798 100644 --- a/libs/design/input/examples/src/input-error/input-error.component.html +++ b/libs/design/input/examples/src/input-error/input-error.component.html @@ -7,5 +7,6 @@ @if (control.errors?.email) { Email is not valid. } +
Hint goes here.

Value: {{ control.value }}

\ No newline at end of file diff --git a/libs/design/input/examples/src/input-hint/input-hint.component.html b/libs/design/input/examples/src/input-hint/input-hint.component.html new file mode 100644 index 0000000000..ca9886d677 --- /dev/null +++ b/libs/design/input/examples/src/input-hint/input-hint.component.html @@ -0,0 +1,5 @@ + + + +
Hint goes here.
+
\ No newline at end of file diff --git a/libs/design/input/examples/src/input-hint/input-hint.component.ts b/libs/design/input/examples/src/input-hint/input-hint.component.ts new file mode 100644 index 0000000000..08e457a045 --- /dev/null +++ b/libs/design/input/examples/src/input-hint/input-hint.component.ts @@ -0,0 +1,23 @@ +import { + ChangeDetectionStrategy, + Component, +} from '@angular/core'; + +import { + DaffFormFieldModule, + DaffInputModule, +} from '@daffodil/design'; + +@Component({ + // eslint-disable-next-line @angular-eslint/component-selector + selector: 'input-hint', + templateUrl: './input-hint.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [ + DaffFormFieldModule, + DaffInputModule, + ], +}) +export class InputHintComponent { +} diff --git a/libs/design/input/examples/src/input-with-form-field/input-with-form-field.component.html b/libs/design/input/examples/src/input-with-form-field/input-with-form-field.component.html index ef1b7b5a94..6a88acbbff 100644 --- a/libs/design/input/examples/src/input-with-form-field/input-with-form-field.component.html +++ b/libs/design/input/examples/src/input-with-form-field/input-with-form-field.component.html @@ -1,5 +1,6 @@ - - + + + \ No newline at end of file diff --git a/libs/design/input/examples/src/input-with-form-field/input-with-form-field.component.ts b/libs/design/input/examples/src/input-with-form-field/input-with-form-field.component.ts index 402922bf67..d96190dd53 100644 --- a/libs/design/input/examples/src/input-with-form-field/input-with-form-field.component.ts +++ b/libs/design/input/examples/src/input-with-form-field/input-with-form-field.component.ts @@ -2,19 +2,27 @@ import { ChangeDetectionStrategy, Component, } from '@angular/core'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { + faUser, + faCircleXmark, +} from '@fortawesome/free-solid-svg-icons'; import { DaffFormFieldModule, DaffInputModule, } from '@daffodil/design'; + @Component({ // eslint-disable-next-line @angular-eslint/component-selector selector: 'input-with-form-field', templateUrl: './input-with-form-field.component.html', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, - imports: [DaffFormFieldModule, DaffInputModule], + imports: [DaffFormFieldModule, DaffInputModule, FontAwesomeModule], }) export class InputWithFormFieldComponent { + faUser = faUser; + faCircleXmark = faCircleXmark; } diff --git a/libs/design/input/examples/src/password-with-form-field/password-with-form-field.component.html b/libs/design/input/examples/src/password-with-form-field/password-with-form-field.component.html new file mode 100644 index 0000000000..da46aaef29 --- /dev/null +++ b/libs/design/input/examples/src/password-with-form-field/password-with-form-field.component.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libs/design/input/examples/src/password-with-form-field/password-with-form-field.component.ts b/libs/design/input/examples/src/password-with-form-field/password-with-form-field.component.ts new file mode 100644 index 0000000000..c576fb6fca --- /dev/null +++ b/libs/design/input/examples/src/password-with-form-field/password-with-form-field.component.ts @@ -0,0 +1,25 @@ +import { + ChangeDetectionStrategy, + Component, +} from '@angular/core'; +import { + ReactiveFormsModule, + UntypedFormControl, +} from '@angular/forms'; + +import { + DaffFormFieldModule, + DaffInputModule, +} from '@daffodil/design'; + +@Component({ + // eslint-disable-next-line @angular-eslint/component-selector + selector: 'password-with-form-field', + templateUrl: './password-with-form-field.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [DaffFormFieldModule, DaffInputModule, ReactiveFormsModule], +}) +export class PasswordWithFormFieldComponent { + control: UntypedFormControl = new UntypedFormControl(); +} diff --git a/libs/design/src/atoms/form/error-message/error-message.component.scss b/libs/design/src/atoms/form/error-message/error-message.component.scss index 78fc8391f7..71291cd003 100644 --- a/libs/design/src/atoms/form/error-message/error-message.component.scss +++ b/libs/design/src/atoms/form/error-message/error-message.component.scss @@ -3,5 +3,6 @@ :host { display: block; font-size: t.$small-font-size; - margin-top: 5px; + margin-top: 4px; + padding-left: 16px; } diff --git a/libs/design/src/atoms/form/form-field/form-field/form-field-theme.scss b/libs/design/src/atoms/form/form-field/form-field/form-field-theme.scss index e24c7cc7fd..0231dc5818 100644 --- a/libs/design/src/atoms/form/form-field/form-field/form-field-theme.scss +++ b/libs/design/src/atoms/form/form-field/form-field/form-field-theme.scss @@ -11,10 +11,6 @@ $neutral: core.daff-map-deep-get($theme, 'core.neutral'); .daff-form-field { - &:has(.error) .error { - color: theming.daff-color(theming.$daff-red, 60); - } - &__control { background: $base; border: 1px solid theming.daff-illuminate($base, $neutral, 6); diff --git a/libs/design/src/atoms/form/form-field/form-field/form-field.component.html b/libs/design/src/atoms/form/form-field/form-field/form-field.component.html index 02f36e314b..5dff25d379 100644 --- a/libs/design/src/atoms/form/form-field/form-field/form-field.component.html +++ b/libs/design/src/atoms/form/form-field/form-field/form-field.component.html @@ -5,6 +5,9 @@ [class.daff-valid]="isValid" [class.daff-filled]="isFilled" > + + +
+ + + @if (_control?.ngControl?.touched) { diff --git a/libs/design/src/atoms/form/form-field/form-field/form-field.component.scss b/libs/design/src/atoms/form/form-field/form-field/form-field.component.scss index c9bcbc3f36..f8a36d0f4b 100644 --- a/libs/design/src/atoms/form/form-field/form-field/form-field.component.scss +++ b/libs/design/src/atoms/form/form-field/form-field/form-field.component.scss @@ -2,13 +2,9 @@ display: block; position: relative; - &:has(.error) { - padding-bottom: 32px; - } - &__control { border-radius: 4px; - display: inline-block; + display: flex; font-size: 16px; height: inherit; line-height: 16px; @@ -48,14 +44,40 @@ display: inline-block; pointer-events: none; position: absolute; - right: 16px; - } + top: 50%; + transform: translateY(-50%); + + &--prefix { + left: 16px; + } + + &--suffix { + right: 16px; + } + } + + :has(fa-icon.prefix) > label, + :has(fa-icon.prefix) > input { + padding-left: 28px; + } - .error { + .hint { position: absolute; top: 100%; left: 16px; - padding-top: 8px; + margin-top: 8px; font-size: 12px; } + + &:has(.hint) { + margin-bottom: 24px; + + daff-error-message { + margin-top: 24px; + } + + &:has(daff-error-message) { + margin-bottom: 0px; + } + } } diff --git a/libs/design/src/atoms/form/form-field/form-field/form-field.component.ts b/libs/design/src/atoms/form/form-field/form-field/form-field.component.ts index 322f4acd7a..f31483ff14 100644 --- a/libs/design/src/atoms/form/form-field/form-field/form-field.component.ts +++ b/libs/design/src/atoms/form/form-field/form-field/form-field.component.ts @@ -103,7 +103,7 @@ export class DaffFormFieldComponent implements AfterContentInit, AfterContentChe */ ngAfterContentChecked() { this._validateFormControl(); - if(this._control?.ngControl) { + if (this._control?.ngControl) { this.isError = this._control.ngControl.errors && (this._control.ngControl.touched); this.isValid = !this._control.ngControl.errors && this._control.ngControl.touched; } diff --git a/libs/design/src/atoms/form/input/input-theme.scss b/libs/design/src/atoms/form/input/input-theme.scss index c0f74ecb99..474859c6c8 100644 --- a/libs/design/src/atoms/form/input/input-theme.scss +++ b/libs/design/src/atoms/form/input/input-theme.scss @@ -5,12 +5,8 @@ $base: core.daff-map-deep-get($theme, 'core.base'); $base-contrast: core.daff-map-deep-get($theme, 'core.base-contrast'); - :host { + .daff-input { background: $base; color: $base-contrast; - - &::placeholder { - color: transparent; - } } } diff --git a/libs/design/src/atoms/form/input/input.component.ts b/libs/design/src/atoms/form/input/input.component.ts index 42dddd9ed9..eb15877bee 100644 --- a/libs/design/src/atoms/form/input/input.component.ts +++ b/libs/design/src/atoms/form/input/input.component.ts @@ -6,6 +6,7 @@ import { ElementRef, HostListener, ChangeDetectionStrategy, + HostBinding, } from '@angular/core'; import { NgControl } from '@angular/forms'; @@ -27,6 +28,8 @@ import { DaffFormFieldControl } from '../form-field/form-field-control'; }) export class DaffInputComponent implements DaffFormFieldControl { + @HostBinding('class.daff-input') class = true; + /** * Has the form been submitted. */