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 @@
+
+
+ Label
+ 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 @@
-
-
+
+
Label
+
\ 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 @@
+
+
+
+ Label
+
\ 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.
*/