diff --git a/libs/components/src/form-field/form-field.stories.ts b/libs/components/src/form-field/form-field.stories.ts
index f5bb04bff0f..dae747b0395 100644
--- a/libs/components/src/form-field/form-field.stories.ts
+++ b/libs/components/src/form-field/form-field.stories.ts
@@ -10,6 +10,7 @@ import {
} from "@angular/forms";
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
+import { A11yTitleDirective } from "@bitwarden/angular/src/directives/a11y-title.directive";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { AsyncActionsModule } from "../async-actions";
@@ -50,6 +51,7 @@ export default {
TextFieldModule,
BadgeModule,
],
+ declarations: [A11yTitleDirective],
providers: [
{
provide: I18nService,
@@ -237,7 +239,7 @@ export const Readonly: Story = {
Input
-
+
@@ -258,7 +260,7 @@ export const Readonly: Story = {
Input
-
+
@@ -302,14 +304,14 @@ export const ButtonInputGroup: Story = {
Label
-
+
-
+
-
-
+
+
@@ -325,10 +327,10 @@ export const DisabledButtonInputGroup: Story = {
template: /*html*/ `
Label
-
+
-
-
+
+
@@ -345,8 +347,8 @@ export const PartiallyDisabledButtonInputGroup: Story = {
Label
-
-
+
+
diff --git a/libs/components/src/form-field/prefix.directive.ts b/libs/components/src/form-field/prefix.directive.ts
index bcfc9d01fe4..34fcbf85233 100644
--- a/libs/components/src/form-field/prefix.directive.ts
+++ b/libs/components/src/form-field/prefix.directive.ts
@@ -1,34 +1,20 @@
-import { AfterContentInit, Directive, HostBinding, Input, OnInit, Optional } from "@angular/core";
+import { Directive, HostBinding, Input, OnInit, Optional } from "@angular/core";
import { BitIconButtonComponent } from "../icon-button/icon-button.component";
-import { BitFormFieldComponent } from "./form-field.component";
-
@Directive({
selector: "[bitPrefix]",
})
-export class BitPrefixDirective implements OnInit, AfterContentInit {
+export class BitPrefixDirective implements OnInit {
@HostBinding("class") @Input() get classList() {
return ["tw-text-muted"];
}
- @HostBinding("attr.aria-describedby")
- protected ariaDescribedBy: string;
-
- constructor(
- @Optional() private parentFormField: BitFormFieldComponent,
- @Optional() private iconButtonComponent: BitIconButtonComponent,
- ) {}
+ constructor(@Optional() private iconButtonComponent: BitIconButtonComponent) {}
ngOnInit() {
if (this.iconButtonComponent) {
this.iconButtonComponent.size = "small";
}
}
-
- ngAfterContentInit() {
- if (this.parentFormField?.label?.id) {
- this.ariaDescribedBy = this.parentFormField.label.id;
- }
- }
}
diff --git a/libs/components/src/form-field/suffix.directive.ts b/libs/components/src/form-field/suffix.directive.ts
index 39fcce916cc..28736ce78a9 100644
--- a/libs/components/src/form-field/suffix.directive.ts
+++ b/libs/components/src/form-field/suffix.directive.ts
@@ -1,34 +1,20 @@
-import { AfterContentInit, Directive, HostBinding, Input, OnInit, Optional } from "@angular/core";
+import { Directive, HostBinding, Input, OnInit, Optional } from "@angular/core";
import { BitIconButtonComponent } from "../icon-button/icon-button.component";
-import { BitFormFieldComponent } from "./form-field.component";
-
@Directive({
selector: "[bitSuffix]",
})
-export class BitSuffixDirective implements OnInit, AfterContentInit {
+export class BitSuffixDirective implements OnInit {
@HostBinding("class") @Input() get classList() {
return ["tw-text-muted"];
}
- @HostBinding("attr.aria-describedby")
- protected ariaDescribedBy: string;
-
- constructor(
- @Optional() private parentFormField: BitFormFieldComponent,
- @Optional() private iconButtonComponent: BitIconButtonComponent,
- ) {}
+ constructor(@Optional() private iconButtonComponent: BitIconButtonComponent) {}
ngOnInit() {
if (this.iconButtonComponent) {
this.iconButtonComponent.size = "small";
}
}
-
- ngAfterContentInit() {
- if (this.parentFormField?.label?.id) {
- this.ariaDescribedBy = this.parentFormField.label.id;
- }
- }
}
diff --git a/libs/components/src/form/forms.mdx b/libs/components/src/form/forms.mdx
index 5ce129bf301..fbb3a20e518 100644
--- a/libs/components/src/form/forms.mdx
+++ b/libs/components/src/form/forms.mdx
@@ -152,6 +152,12 @@ If a checkbox group has more than 4 options a
helper text.
- **Example:** "Billing Email is required if owned by a business".
+### Icon Buttons in Form Fields
+
+When adding prefix or suffix icon buttons to a form field, be sure to use the `appA11yTitle`
+directive to provide a label for screenreaders. Typically, the label should follow this pattern:
+`{Action} {field label}`, i.e. "Copy username".
+
### Form Field Errors
- When a resting field is filled out, validation is triggered when the user de-focuses the field