From 4449d8baf6506ffc82f1609ffd7c83e5cb94631a Mon Sep 17 00:00:00 2001 From: Bryan Cunningham Date: Tue, 19 Aug 2025 15:15:41 -0400 Subject: [PATCH 01/34] [CL-689][CL-799] Fix Icon button a11y errors (#15750) * Throw error if appA11yTitle is null in icon button * Add required label input * Fix icon button errors in CL components and storeis * fix popover aria-label errors * remove commented code * add labels to icon buttons in browser * add labels to icon buttons in web * add labels to icon buttons in license * add labels to icon buttons in send * add labels to icon buttons in angular * fix missing pipe error * fix sso icon button missed in error * update labels in vault * add section expand button label * Adding labels to icon buttons * Add lint rule to not allow icon buttons without label input * rename util file * trigger updates on title change * update eslint rule name and folder * add edit collection label to vault headers * fix web header story label * add show/hide summary labels * update summary message * fix breadcrumbs label message * fix JSDoc to use correct input * remove commented code * use label as aria-label always. Remove init function * add moreBreadcrumbs translation message to other apps * add @bitwarden/team-ui-foundation as code owner for component eslint rules * switch title to const variable * add jsdoc comment on what the label input is used for * [PM-22415] Tax ID notifications for Organizations and Providers (#15996) * [NO LOGIC] Rename BillableEntity to BitwardenSubscriber This helps us maintain paraody with server where we call this choice type ISubscriber. I chose BitwardenSubscriber to avoid overlap with RxJS * [NO LOGIC] Move subscriber-billing.client to clients folder * [NO LOGIC] Move organization warnings under organization folder * Move getWarnings from OrganizationBillingApiService to new OrganizationBillingClient I'd like us to move away from stashing so much in libs and utilizing the JsLibServicesModule when it's not necessary to do so. These are invocations used exclusively by the Web Vault and, until that changes, they should be treated as such * Refactor OrganizationWarningsService There was a case added to the Inactive Subscription warning for a free trial, but free trials do not represent inactive subscriptions so this was semantically incorrect. This creates another method that pulls the free trial warning and shows a dialog asking the user to subscribe if they're on one. * Implement Tax ID Warnings throughout Admin Console and Provider Portal * Fix linting error * Jimmy's feedback * remove duplicate messages keys * revert changes to popover stories * add back dupe myItems key for now as it was already here * fix directive type errors * remove variable left in error from merge conflict * revert unintentional change to reports layout * add back reports change --------- Co-authored-by: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> --- .github/CODEOWNERS | 1 + apps/browser/src/_locales/en/messages.json | 4 ++ .../settings/blocked-domains.component.html | 2 +- .../settings/excluded-domains.component.html | 2 +- .../popup/components/pop-out.component.html | 2 +- .../popup/layout/popup-header.component.html | 3 +- .../popup/layout/popup-layout.stories.ts | 32 +++++------- .../add-edit/send-add-edit.component.html | 2 +- .../add-edit/add-edit-v2.component.html | 2 +- .../item-copy-actions.component.html | 30 +++++------ .../item-more-options.component.html | 3 +- .../vault-header-v2.component.html | 2 +- .../vault-list-items-container.component.html | 5 +- .../vault-v2/view-v2/view-v2.component.html | 2 +- .../popup/settings/folders-v2.component.html | 2 +- .../trash-list-items-container.component.html | 3 +- apps/desktop/src/locales/en/messages.json | 4 ++ .../vault-header/vault-header.component.html | 1 + .../manage/group-add-edit.component.html | 2 +- .../manage/groups.component.html | 4 +- .../members/members.component.html | 4 +- .../access-selector-dialog.stories.ts | 2 +- .../access-selector.component.html | 2 +- .../collection-dialog.component.html | 2 +- .../emergency-access-add-edit.component.html | 2 +- .../emergency-access.component.html | 4 +- .../two-factor-setup-yubikey.component.html | 2 +- .../free-bitwarden-families.component.html | 2 +- .../billing-sync-api-key.component.html | 2 +- .../billing-sync-key.component.html | 2 +- .../change-plan-dialog.component.html | 2 +- .../organizations/change-plan.component.html | 2 +- .../sponsoring-org-row.component.html | 2 +- .../pricing-summary.component.html | 4 +- .../reports/reports-layout.component.html | 2 +- .../app/layouts/header/web-header.stories.ts | 2 +- .../product-switcher.component.html | 2 +- .../app/settings/domain-rules.component.html | 3 +- .../src/app/tools/send/send.component.html | 2 +- .../vault-item-dialog.component.html | 2 +- .../vault-cipher-row.component.html | 4 +- .../vault-collection-row.component.html | 2 +- .../vault-items/vault-items.component.html | 2 +- .../vault-header/vault-header.component.html | 2 +- apps/web/src/locales/en/messages.json | 10 ++++ .../device-approvals.component.html | 4 +- .../domain-add-edit-dialog.component.html | 5 +- .../organizations/manage/scim.component.html | 8 +-- .../add-edit-member-dialog.component.html | 2 +- .../providers/manage/members.component.html | 4 +- .../src/app/auth/sso/sso.component.html | 14 ++--- .../clients/manage-clients.component.html | 2 +- .../app-table-row-scrollable.component.html | 2 +- .../overview/section.component.html | 1 + .../dialog/secret-dialog.component.html | 2 +- .../access/access-list.component.html | 6 +-- .../config/config.component.html | 10 +++- .../service-accounts-list.component.html | 6 +-- .../access-policy-selector.component.html | 3 +- .../shared/projects-list.component.html | 9 ++-- .../shared/secrets-list.component.html | 9 ++-- eslint.config.mjs | 6 +++ .../spotlight/spotlight.component.html | 3 +- .../input-password.component.html | 4 +- .../src/a11y/a11y-title.directive.ts | 21 ++++---- .../src/a11y/set-a11y-title-and-aria-label.ts | 16 ++++++ .../components/src/async-actions/in-forms.mdx | 8 ++- .../src/async-actions/in-forms.stories.ts | 7 ++- .../src/async-actions/standalone.mdx | 2 +- .../src/async-actions/standalone.stories.ts | 2 +- .../src/banner/banner.component.html | 3 +- .../breadcrumbs/breadcrumbs.component.html | 1 + .../src/breadcrumbs/breadcrumbs.component.ts | 4 +- .../src/breadcrumbs/breadcrumbs.stories.ts | 13 +++++ .../src/dialog/dialog/dialog.component.html | 3 +- .../src/dialog/dialog/dialog.stories.ts | 10 ++-- .../src/disclosure/disclosure.component.ts | 1 + .../src/disclosure/disclosure.stories.ts | 2 +- .../src/drawer/drawer-header.component.html | 8 +-- .../src/form-field/form-field.stories.ts | 28 +++++----- .../form-field/password-input-toggle.spec.ts | 8 ++- .../password-input-toggle.stories.ts | 4 +- .../src/icon-button/icon-button.component.ts | 25 +++++++-- .../src/icon-button/icon-button.stories.ts | 1 + libs/components/src/item/item.mdx | 4 +- libs/components/src/item/item.stories.ts | 44 ++++++++-------- .../src/navigation/nav-group.component.html | 3 +- .../src/navigation/nav-item.stories.ts | 4 +- .../src/navigation/side-nav.component.html | 2 +- .../src/popover/popover.component.html | 3 +- libs/components/src/section/section.mdx | 2 +- .../components/src/section/section.stories.ts | 16 +++--- .../dialog-virtual-scroll-block.component.ts | 2 +- .../components/kitchen-sink-form.component.ts | 8 ++- .../kitchen-sink-table.component.ts | 2 + .../components/src/toast/toast.component.html | 1 + libs/eslint/components/index.mjs | 3 ++ .../require-label-on-biticonbutton.mjs | 51 +++++++++++++++++++ .../src/components/export.component.html | 2 + ...redential-generator-history.component.html | 2 +- .../src/credential-generator.component.html | 4 +- .../src/password-generator.component.html | 4 +- .../src/username-generator.component.html | 4 +- .../send-add-edit-dialog.component.html | 2 +- .../options/send-options.component.html | 6 +-- .../send-details/send-details.component.html | 2 +- .../send-list-items-container.component.html | 4 +- .../delete-attachment.component.html | 2 +- .../uri-option.component.html | 6 +-- ...dd-edit-custom-field-dialog.component.html | 2 +- .../custom-fields.component.html | 4 +- .../item-details-section.component.html | 2 +- .../login-details-section.component.html | 10 ++-- .../sshkey-section.component.html | 2 +- .../additional-options.component.html | 2 +- .../autofill-options-view.component.html | 4 +- .../card-details-view.component.html | 4 +- .../custom-fields-v2.component.html | 6 +-- .../login-credentials-view.component.html | 8 +-- .../sshkey-view.component.html | 6 +-- .../view-identity-sections.component.html | 18 +++---- .../add-edit-folder-dialog.component.html | 2 +- .../download-attachment.component.html | 2 +- .../password-history-view.component.html | 2 +- 124 files changed, 414 insertions(+), 285 deletions(-) create mode 100644 libs/components/src/a11y/set-a11y-title-and-aria-label.ts create mode 100644 libs/eslint/components/index.mjs create mode 100644 libs/eslint/components/require-label-on-biticonbutton.mjs diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 187f500828c..4b956fd577a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -131,6 +131,7 @@ apps/web/src/translation-constants.ts @bitwarden/team-platform-dev .github/workflows/version-auto-bump.yml @bitwarden/team-platform-dev # ESLint custom rules libs/eslint @bitwarden/team-platform-dev +libs/eslint/components @bitwarden/team-ui-foundation # Typescript tooling tsconfig.base.json @bitwarden/team-platform-dev nx.json @bitwarden/team-platform-dev diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index f8dde376b35..1c27fab6971 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -5579,5 +5579,9 @@ }, "showLess": { "message": "Show less" + }, + "moreBreadcrumbs": { + "message": "More breadcrumbs", + "description": "This is used in the context of a breadcrumb navigation, indicating that there are more items in the breadcrumb trail that are not currently displayed." } } diff --git a/apps/browser/src/autofill/popup/settings/blocked-domains.component.html b/apps/browser/src/autofill/popup/settings/blocked-domains.component.html index 8156525301b..6a08b4483af 100644 --- a/apps/browser/src/autofill/popup/settings/blocked-domains.component.html +++ b/apps/browser/src/autofill/popup/settings/blocked-domains.component.html @@ -30,7 +30,7 @@ diff --git a/apps/browser/src/platform/popup/layout/popup-header.component.html b/apps/browser/src/platform/popup/layout/popup-header.component.html index 014ebc86411..2aac161b9d5 100644 --- a/apps/browser/src/platform/popup/layout/popup-header.component.html +++ b/apps/browser/src/platform/popup/layout/popup-header.component.html @@ -19,8 +19,7 @@ bitIconButton="bwi-angle-left" type="button" *ngIf="showBackButton" - [title]="'back' | i18n" - [attr.aria-label]="'back' | i18n" + [label]="'back' | i18n" [bitAction]="backAction" >

diff --git a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts index aeeed6f65ce..7455921b08b 100644 --- a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts +++ b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts @@ -67,14 +67,10 @@ class ExtensionPoppedContainerComponent {} - + - + @@ -102,13 +98,7 @@ class MockAddButtonComponent {} @Component({ selector: "mock-popout-button", template: ` - + `, imports: [IconButtonModule], }) @@ -278,7 +268,13 @@ class MockSettingsPageComponent {} - + `, @@ -671,17 +667,13 @@ export const WithVirtualScrollChild: Story = { - + diff --git a/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html b/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html index 5d313188d8f..c6ea52aff62 100644 --- a/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html +++ b/apps/browser/src/tools/popup/send-v2/add-edit/send-add-edit.component.html @@ -26,7 +26,7 @@ slot="end" bitIconButton="bwi-trash" [bitAction]="deleteSend" - appA11yTitle="{{ 'delete' | i18n }}" + label="{{ 'delete' | i18n }}" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html index 21b298fb30a..8f184c6a0c1 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html @@ -38,7 +38,7 @@ type="button" buttonType="danger" bitIconButton="bwi-trash" - [appA11yTitle]="'delete' | i18n" + [label]="'delete' | i18n" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html b/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html index 567d5277454..f4cc27171ad 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/item-copy-action/item-copy-actions.component.html @@ -7,7 +7,7 @@ size="small" appCopyField="username" [cipher]="cipher" - [appA11yTitle]="'copyUsername' | i18n" + [label]="'copyUsername' | i18n" > @@ -18,7 +18,7 @@ size="small" appCopyField="password" [cipher]="cipher" - [appA11yTitle]="'copyPassword' | i18n" + [label]="'copyPassword' | i18n" > @@ -28,7 +28,7 @@ size="small" appCopyField="totp" [cipher]="cipher" - [appA11yTitle]="'copyVerificationCode' | i18n" + [label]="'copyVerificationCode' | i18n" > @@ -40,7 +40,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]="'copyFieldCipherName' | i18n: singleCopyableLogin.key : cipher.name" + [label]="'copyFieldCipherName' | i18n: singleCopyableLogin.key : cipher.name" [appCopyField]="singleCopyableLogin.field" [cipher]="cipher" > @@ -49,7 +49,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" + [label]=" hasLoginValues ? ('copyInfoTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n) " [disabled]="!hasLoginValues" @@ -86,7 +86,7 @@ size="small" appCopyField="cardNumber" [cipher]="cipher" - [appA11yTitle]="'copyNumber' | i18n" + [label]="'copyNumber' | i18n" > @@ -96,7 +96,7 @@ size="small" appCopyField="securityCode" [cipher]="cipher" - [appA11yTitle]="'copySecurityCode' | i18n" + [label]="'copySecurityCode' | i18n" > @@ -107,7 +107,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]="'copyFieldCipherName' | i18n: singleCopyableCard.key : cipher.name" + [label]="'copyFieldCipherName' | i18n: singleCopyableCard.key : cipher.name" [appCopyField]="singleCopyableCard.field" [cipher]="cipher" showToast @@ -117,7 +117,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" + [label]=" hasCardValues ? ('copyInfoTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n) " [disabled]="!hasCardValues" @@ -142,7 +142,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]="'copyFieldCipherName' | i18n: singleCopyableIdentity.key : cipher.name" + [label]="'copyFieldCipherName' | i18n: singleCopyableIdentity.key : cipher.name" [appCopyField]="singleCopyableIdentity.field" [cipher]="cipher" showToast @@ -152,7 +152,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" + [label]=" hasIdentityValues ? ('copyInfoTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n) " [disabled]="!hasIdentityValues" @@ -180,9 +180,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" - hasSecureNoteValue ? ('copyNoteTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n) - " + [label]="hasSecureNoteValue ? ('copyNoteTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n)" appCopyField="secureNote" [cipher]="cipher" > @@ -193,9 +191,7 @@ type="button" bitIconButton="bwi-clone" size="small" - [appA11yTitle]=" - hasSshKeyValues ? ('copyInfoTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n) - " + [label]="hasSshKeyValues ? ('copyInfoTitle' | i18n: cipher.name) : ('noValuesToCopy' | i18n)" [disabled]="!hasSshKeyValues" [bitMenuTriggerFor]="sshKeyOptions" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html index 962f0c914f5..42e2779679a 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html @@ -3,8 +3,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - [attr.aria-label]="'moreOptionsLabel' | i18n: cipher.name" - [title]="'moreOptionsTitle' | i18n: cipher.name" + [label]="'moreOptionsLabel' | i18n: cipher.name" [disabled]="decryptionFailure" [bitMenuTriggerFor]="moreOptions" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html index 91feaa433a9..1ab162b56fb 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html @@ -8,7 +8,7 @@ bitIconButton="bwi-sliders" [buttonType]="'muted'" [bitDisclosureTriggerFor]="disclosureRef" - [appA11yTitle]="'filterVault' | i18n" + [label]="'filterVault' | i18n" aria-describedby="filters-applied" >

diff --git a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.html index 8c76db600ae..9b8380a4214 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.html @@ -33,7 +33,7 @@ type="button" buttonType="danger" bitIconButton="bwi-trash" - [appA11yTitle]="(cipher.isDeleted ? 'deleteForever' : 'delete') | i18n" + [label]="(cipher.isDeleted ? 'deleteForever' : 'delete') | i18n" > diff --git a/apps/browser/src/vault/popup/settings/folders-v2.component.html b/apps/browser/src/vault/popup/settings/folders-v2.component.html index 8cea05f9c17..b36b5affc23 100644 --- a/apps/browser/src/vault/popup/settings/folders-v2.component.html +++ b/apps/browser/src/vault/popup/settings/folders-v2.component.html @@ -25,7 +25,7 @@ slot="end" type="button" (click)="openAddEditFolderDialog(folder)" - [appA11yTitle]="'editFolderWithName' | i18n: folder.name" + [label]="'editFolderWithName' | i18n: folder.name" bitIconButton="bwi-pencil-square" class="tw-self-end" data-testid="edit-folder-button" diff --git a/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html b/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html index 11ed2674178..d1e70390844 100644 --- a/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html +++ b/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html @@ -37,8 +37,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - [attr.aria-label]="'moreOptionsLabel' | i18n: cipher.name" - [title]="'moreOptionsTitle' | i18n: cipher.name" + [label]="'moreOptionsLabel' | i18n: cipher.name" [bitMenuTriggerFor]="moreOptions" > diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 72d40ed750f..d99d3686d12 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -4077,5 +4077,9 @@ }, "enableAutotypeDescription": { "message": "Bitwarden does not validate input locations, be sure you are in the right window and field before using the shortcut." + }, + "moreBreadcrumbs": { + "message": "More breadcrumbs", + "description": "This is used in the context of a breadcrumb navigation, indicating that there are more items in the breadcrumb trail that are not currently displayed." } } diff --git a/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.html b/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.html index 50d34227b56..9c3e607d6eb 100644 --- a/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.html +++ b/apps/web/src/app/admin-console/organizations/collections/vault-header/vault-header.component.html @@ -34,6 +34,7 @@ [bitMenuTriggerFor]="editCollectionMenu" size="small" type="button" + [label]="'editCollection' | i18n" > diff --git a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html index 101512dea04..cc90d10fb4a 100644 --- a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html +++ b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html @@ -80,7 +80,7 @@ bitIconButton="bwi-trash" bitFormButton [bitAction]="delete" - [appA11yTitle]="'delete' | i18n" + [label]="'delete' | i18n" > diff --git a/apps/web/src/app/admin-console/organizations/manage/groups.component.html b/apps/web/src/app/admin-console/organizations/manage/groups.component.html index 4518513ba7d..62d0b5b874b 100644 --- a/apps/web/src/app/admin-console/organizations/manage/groups.component.html +++ b/apps/web/src/app/admin-console/organizations/manage/groups.component.html @@ -46,7 +46,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > @@ -82,7 +82,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > diff --git a/apps/web/src/app/admin-console/organizations/members/members.component.html b/apps/web/src/app/admin-console/organizations/members/members.component.html index 49946806efc..7e0aa465bf3 100644 --- a/apps/web/src/app/admin-console/organizations/members/members.component.html +++ b/apps/web/src/app/admin-console/organizations/members/members.component.html @@ -106,7 +106,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" *ngIf="showUserManagementControls$ | async" > @@ -350,7 +350,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector-dialog.stories.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector-dialog.stories.ts index a803f6ef7b5..5cb61197b99 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector-dialog.stories.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector-dialog.stories.ts @@ -51,7 +51,7 @@ const render: Story["render"] = (args) => ({ buttonType="danger" size="default" title="Delete" - aria-label="Delete"> + label="Delete"> `, diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html index e0ffc9a4bce..116af15f579 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html @@ -122,7 +122,7 @@ type="button" bitIconButton="bwi-close" buttonType="muted" - appA11yTitle="{{ 'remove' | i18n }} {{ item.labelName }}" + label="{{ 'remove' | i18n }} {{ item.labelName }}" [disabled]="disabled" (click)="selectionList.deselectItem(item.id); handleBlur()" > diff --git a/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html b/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html index 4a91fcc2a41..dec257b3741 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html +++ b/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.html @@ -143,7 +143,7 @@ buttonType="danger" class="tw-ml-auto" bitFormButton - [appA11yTitle]="'delete' | i18n" + [label]="'delete' | i18n" [bitAction]="delete" [disabled]="loading" > diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.html b/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.html index 6e87d66d18b..1c04c03a8d2 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.html +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.html @@ -62,7 +62,7 @@ buttonType="danger" [bitAction]="delete" *ngIf="editMode" - appA11yTitle="{{ 'delete' | i18n }}" + label="{{ 'delete' | i18n }}" > diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html index 8a802e4f6af..70165a94fc3 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html @@ -89,7 +89,7 @@ @@ -212,7 +212,7 @@ diff --git a/apps/web/src/app/auth/settings/two-factor/two-factor-setup-yubikey.component.html b/apps/web/src/app/auth/settings/two-factor/two-factor-setup-yubikey.component.html index 1df1e52f7e4..dbad422a32e 100644 --- a/apps/web/src/app/auth/settings/two-factor/two-factor-setup-yubikey.component.html +++ b/apps/web/src/app/auth/settings/two-factor/two-factor-setup-yubikey.component.html @@ -39,7 +39,7 @@ type="button" buttonType="danger" (click)="remove(i)" - appA11yTitle="{{ 'remove' | i18n }}" + label="{{ 'remove' | i18n }}" > diff --git a/apps/web/src/app/billing/members/free-bitwarden-families.component.html b/apps/web/src/app/billing/members/free-bitwarden-families.component.html index ddf7c506745..697a5963a71 100644 --- a/apps/web/src/app/billing/members/free-bitwarden-families.component.html +++ b/apps/web/src/app/billing/members/free-bitwarden-families.component.html @@ -53,7 +53,7 @@ bitIconButton="bwi-ellipsis-v" buttonType="main" [bitMenuTriggerFor]="appListDropdown" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > @if (!isSelfHosted && !sponsoredFamily.validUntil) { diff --git a/apps/web/src/app/billing/organizations/billing-sync-api-key.component.html b/apps/web/src/app/billing/organizations/billing-sync-api-key.component.html index a09000ef55f..465a50ec8c3 100644 --- a/apps/web/src/app/billing/organizations/billing-sync-api-key.component.html +++ b/apps/web/src/app/billing/organizations/billing-sync-api-key.component.html @@ -33,7 +33,7 @@ showToast [valueLabel]="'billingSyncKey' | i18n" [appCopyClick]="clientSecret" - [appA11yTitle]="'copyValue' | i18n" + [label]="'copyValue' | i18n" >

diff --git a/apps/web/src/app/billing/organizations/billing-sync-key.component.html b/apps/web/src/app/billing/organizations/billing-sync-key.component.html index 9736351deca..94a81140344 100644 --- a/apps/web/src/app/billing/organizations/billing-sync-key.component.html +++ b/apps/web/src/app/billing/organizations/billing-sync-key.component.html @@ -33,7 +33,7 @@ bitIconButton="bwi-trash" bitFormButton [bitAction]="deleteConnection" - appA11yTitle="{{ 'delete' | i18n }}" + label="{{ 'delete' | i18n }}" > diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html index ace3d749a3f..f899b8eccb4 100644 --- a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html +++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html @@ -359,7 +359,7 @@ type="button" [bitIconButton]="totalOpened ? 'bwi-angle-down' : 'bwi-angle-up'" size="small" - aria-hidden="true" + [label]="totalOpened ? ('hidePricingSummary' | i18n) : ('showPricingSummary' | i18n)" >

diff --git a/apps/web/src/app/billing/organizations/change-plan.component.html b/apps/web/src/app/billing/organizations/change-plan.component.html index 75a12122d19..1cd15a7c836 100644 --- a/apps/web/src/app/billing/organizations/change-plan.component.html +++ b/apps/web/src/app/billing/organizations/change-plan.component.html @@ -8,7 +8,7 @@ type="button" size="small" class="tw-float-right" - appA11yTitle="{{ 'cancel' | i18n }}" + label="{{ 'cancel' | i18n }}" (click)="cancel()" >

{{ "changeBillingPlan" | i18n }}

diff --git a/apps/web/src/app/billing/settings/sponsoring-org-row.component.html b/apps/web/src/app/billing/settings/sponsoring-org-row.component.html index 1e5690cd85a..5167c0a5c32 100644 --- a/apps/web/src/app/billing/settings/sponsoring-org-row.component.html +++ b/apps/web/src/app/billing/settings/sponsoring-org-row.component.html @@ -12,7 +12,7 @@ bitIconButton="bwi-ellipsis-v" buttonType="main" [bitMenuTriggerFor]="appListDropdown" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" >

diff --git a/apps/web/src/app/dirt/reports/reports-layout.component.html b/apps/web/src/app/dirt/reports/reports-layout.component.html index 283d9213cc7..a27556a7aa9 100644 --- a/apps/web/src/app/dirt/reports/reports-layout.component.html +++ b/apps/web/src/app/dirt/reports/reports-layout.component.html @@ -2,7 +2,7 @@
diff --git a/apps/web/src/app/layouts/header/web-header.stories.ts b/apps/web/src/app/layouts/header/web-header.stories.ts index 9715dbf8cd3..7abddf01f2b 100644 --- a/apps/web/src/app/layouts/header/web-header.stories.ts +++ b/apps/web/src/app/layouts/header/web-header.stories.ts @@ -48,7 +48,7 @@ class MockStateService { @Component({ selector: "product-switcher", - template: ``, + template: ``, standalone: false, }) class MockProductSwitcher {} diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher.component.html b/apps/web/src/app/layouts/product-switcher/product-switcher.component.html index f1942a02c20..a44f05a7ed7 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher.component.html +++ b/apps/web/src/app/layouts/product-switcher/product-switcher.component.html @@ -3,7 +3,7 @@ bitIconButton="bwi bwi-fw bwi-filter" [bitMenuTriggerFor]="content?.menu" [buttonType]="buttonType" - [attr.aria-label]="'switchProducts' | i18n" + [label]="'switchProducts' | i18n" *ngIf="products$ | async" > diff --git a/apps/web/src/app/settings/domain-rules.component.html b/apps/web/src/app/settings/domain-rules.component.html index 8ebeecb429f..880e2a6da0f 100644 --- a/apps/web/src/app/settings/domain-rules.component.html +++ b/apps/web/src/app/settings/domain-rules.component.html @@ -32,7 +32,7 @@ type="button" buttonType="danger" (click)="remove(i)" - appA11yTitle="{{ 'remove' | i18n }}" + label="{{ 'remove' | i18n }}" >
diff --git a/apps/web/src/app/tools/send/send.component.html b/apps/web/src/app/tools/send/send.component.html index 042046b85ff..b79f50311ed 100644 --- a/apps/web/src/app/tools/send/send.component.html +++ b/apps/web/src/app/tools/send/send.component.html @@ -156,7 +156,7 @@ type="button" [bitMenuTriggerFor]="sendOptions" bitIconButton="bwi-ellipsis-v" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > @@ -101,7 +101,7 @@ bitIconButton="bwi-ellipsis-v" type="button" appStopProp - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > diff --git a/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html b/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html index ad2886b1e59..7cd5129d3f0 100644 --- a/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html +++ b/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.html @@ -65,7 +65,7 @@ size="small" bitIconButton="bwi-ellipsis-v" type="button" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" appStopProp > } diff --git a/apps/web/src/app/vault/components/vault-items/vault-items.component.html b/apps/web/src/app/vault/components/vault-items/vault-items.component.html index ef928903a72..5ddccf6a395 100644 --- a/apps/web/src/app/vault/components/vault-items/vault-items.component.html +++ b/apps/web/src/app/vault/components/vault-items/vault-items.component.html @@ -56,7 +56,7 @@ bitIconButton="bwi-ellipsis-v" size="small" type="button" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > @@ -67,8 +67,7 @@ bitIconButton="bwi-trash" buttonType="danger" size="default" - title="{{ 'delete' | i18n }}" - aria-label="Delete" + label="{{ 'delete' | i18n }}" [bitAction]="deleteDomain" type="submit" bitFormButton diff --git a/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/scim.component.html b/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/scim.component.html index 7ade2e6c63d..38cb077c623 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/scim.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/scim.component.html @@ -29,7 +29,7 @@ bitSuffix bitIconButton="bwi-clone" [bitAction]="copyScimUrl" - [appA11yTitle]="'copyScimUrl' | i18n" + [label]="'copyScimUrl' | i18n" > @@ -46,7 +46,7 @@ bitSuffix [bitIconButton]="showScimKey ? 'bwi-eye-slash' : 'bwi-eye'" [bitAction]="toggleScimKey" - [appA11yTitle]="'toggleVisibility' | i18n" + [label]="'toggleVisibility' | i18n" > {{ "scimApiKeyHelperText" | i18n }} diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.html index 60993f5570c..08e694aa45a 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.html @@ -58,7 +58,7 @@ bitIconButton="bwi-trash" buttonType="danger" bitFormButton - [appA11yTitle]="'delete' | i18n" + [label]="'delete' | i18n" [bitAction]="delete" [disabled]="loading" > diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.html index f203b7a934a..07ccd997b96 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/members.component.html @@ -79,7 +79,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > @@ -193,7 +193,7 @@ bitSuffix type="button" [appCopyClick]="signedOutCallbackPath" - [appA11yTitle]="'copyValue' | i18n" + [label]="'copyValue' | i18n" > @@ -336,7 +336,7 @@ bitSuffix type="button" [appCopyClick]="spEntityId" - [appA11yTitle]="'copyValue' | i18n" + [label]="'copyValue' | i18n" > @@ -348,7 +348,7 @@ bitSuffix type="button" [appCopyClick]="spEntityIdStatic" - [appA11yTitle]="'copyValue' | i18n" + [label]="'copyValue' | i18n" > @@ -360,14 +360,14 @@ bitSuffix type="button" [appLaunchClick]="spMetadataUrl" - [appA11yTitle]="'launch' | i18n" + [label]="'launch' | i18n" > @@ -379,7 +379,7 @@ bitSuffix type="button" [appCopyClick]="spAcsUrl" - [appA11yTitle]="'copyValue' | i18n" + [label]="'copyValue' | i18n" > diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html index 043ce65b961..2ab82bd837b 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.html @@ -86,7 +86,7 @@ type="button" bitIconButton="bwi-ellipsis-v" size="small" - appA11yTitle="{{ 'options' | i18n }}" + label="{{ 'options' | i18n }}" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/overview/section.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/overview/section.component.html index ab7c67c7b22..e7f9692beb3 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/overview/section.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/overview/section.component.html @@ -7,6 +7,7 @@ (click)="toggle()" [attr.aria-expanded]="open" [attr.aria-controls]="contentId" + [label]="'toggleVisibility' | i18n" >
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.html index 24168d0b025..3a2c858ac31 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.html @@ -95,7 +95,7 @@ buttonType="danger" bitIconButton="bwi-trash" bitFormButton - [appA11yTitle]="'delete' | i18n" + [label]="'delete' | i18n" [bitAction]="delete" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-list.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-list.component.html index fbb0dd8888a..3399b550ba5 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-list.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-list.component.html @@ -40,8 +40,7 @@ bitIconButton="bwi-ellipsis-v" buttonType="main" [bitMenuTriggerFor]="tableMenu" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" > @@ -65,8 +64,7 @@ type="button" bitIconButton="bwi-ellipsis-v" buttonType="main" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" [bitMenuTriggerFor]="tokenMenu" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/config/config.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/config/config.component.html index b17e47a39ec..11f8e0b9b77 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/config/config.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/config/config.component.html @@ -11,12 +11,19 @@ type="button" bitIconButton="bwi-clone" [bitAction]="copyIdentityUrl" + [label]="'copyCustomField' | i18n: identityUrl" > {{ "apiUrl" | i18n }} - +
@@ -27,6 +34,7 @@ type="button" bitIconButton="bwi-clone" [bitAction]="copyOrganizationId" + [label]="'copyCustomField' | i18n: organizationId" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.html index bfb7b985423..3d7fc9715c3 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.html @@ -39,8 +39,7 @@ type="button" bitIconButton="bwi-ellipsis-v" buttonType="main" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" [bitMenuTriggerFor]="tableMenu" > @@ -72,8 +71,7 @@ type="button" bitIconButton="bwi-ellipsis-v" buttonType="main" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" [bitMenuTriggerFor]="serviceAccountMenu" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.html index c8a50175781..d01faae4e6e 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.html @@ -67,8 +67,7 @@ buttonType="main" size="default" [disabled]="disabled" - [attr.title]="'remove' | i18n" - [attr.aria-label]="'remove' | i18n" + [label]="'remove' | i18n" (click)="selectionList.deselectItem(item.id); handleBlur()" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.html index bc1655d8b28..236af0d414c 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.html @@ -43,8 +43,7 @@ bitIconButton="bwi-ellipsis-v" buttonType="main" [bitMenuTriggerFor]="tableMenu" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" *ngIf="showMenus" > @@ -77,8 +76,7 @@ bitIconButton="bwi-clone" buttonType="main" size="small" - [title]="'copyUuid' | i18n" - [attr.aria-label]="'copyUuid' | i18n" + [label]="'copyUuid' | i18n" (click)="copyProjectUuidToClipboard(project.id)" > @@ -94,8 +92,7 @@ bitIconButton="bwi-ellipsis-v" buttonType="main" [bitMenuTriggerFor]="projectMenu" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" *ngIf="showMenus" > diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.html index 859c7417eb8..e5d22a01502 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.html +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.html @@ -45,8 +45,7 @@ type="button" bitIconButton="bwi-ellipsis-v" buttonType="main" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" [bitMenuTriggerFor]="tableMenu" > @@ -78,8 +77,7 @@ bitIconButton="bwi-clone" buttonType="main" size="small" - [title]="'copyUuid' | i18n" - [attr.aria-label]="'copyUuid' | i18n" + [label]="'copyUuid' | i18n" (click)="copySecretUuidEvent.emit(secret.id)" > @@ -108,8 +106,7 @@ type="button" bitIconButton="bwi-ellipsis-v" buttonType="main" - [title]="'options' | i18n" - [attr.aria-label]="'options' | i18n" + [label]="'options' | i18n" [bitMenuTriggerFor]="secretMenu" > diff --git a/eslint.config.mjs b/eslint.config.mjs index c4018b7625e..c745f073fc8 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -12,6 +12,7 @@ import angularRxjs from "eslint-plugin-rxjs-angular"; import storybook from "eslint-plugin-storybook"; import platformPlugins from "./libs/eslint/platform/index.mjs"; +import componentPlugins from "./libs/eslint/components/index.mjs"; export default tseslint.config( ...storybook.configs["flat/recommended"], @@ -174,6 +175,7 @@ export default tseslint.config( plugins: { "@angular-eslint/template": angular.templatePlugin, tailwindcss: eslintPluginTailwindCSS, + "@bitwarden/components": componentPlugins, }, rules: { "@angular-eslint/template/button-has-type": "error", @@ -188,6 +190,10 @@ export default tseslint.config( "tailwindcss/enforces-negative-arbitrary-values": "error", "tailwindcss/enforces-shorthand": "error", "tailwindcss/no-contradicting-classname": "error", + "@bitwarden/components/require-label-on-biticonbutton": [ + "error", + { ignoreIfHas: ["bitPasswordInputToggle"] }, + ], }, }, diff --git a/libs/angular/src/vault/components/spotlight/spotlight.component.html b/libs/angular/src/vault/components/spotlight/spotlight.component.html index e445640cff9..0d0e95e191b 100644 --- a/libs/angular/src/vault/components/spotlight/spotlight.component.html +++ b/libs/angular/src/vault/components/spotlight/spotlight.component.html @@ -18,9 +18,8 @@ size="small" *ngIf="!persistent" (click)="handleDismiss()" - [attr.title]="'close' | i18n" - [attr.aria-label]="'close' | i18n" class="-tw-me-2" + [label]="'close' | i18n" > diff --git a/libs/auth/src/angular/input-password/input-password.component.html b/libs/auth/src/angular/input-password/input-password.component.html index d39215b2d68..d56fe6a27fc 100644 --- a/libs/auth/src/angular/input-password/input-password.component.html +++ b/libs/auth/src/angular/input-password/input-password.component.html @@ -45,7 +45,7 @@ type="button" bitIconButton="bwi-generate" bitSuffix - [appA11yTitle]="'generatePassword' | i18n" + [label]="'generatePassword' | i18n" (click)="generatePassword()" > - + ``` ## `[bitSubmit]` Disabled Form Submit diff --git a/libs/components/src/async-actions/in-forms.stories.ts b/libs/components/src/async-actions/in-forms.stories.ts index dd901cd2477..88383fe85a3 100644 --- a/libs/components/src/async-actions/in-forms.stories.ts +++ b/libs/components/src/async-actions/in-forms.stories.ts @@ -7,6 +7,7 @@ import { delay, of } from "rxjs"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; +import { A11yTitleDirective } from "../a11y"; import { ButtonModule } from "../button"; import { FormFieldModule } from "../form-field"; import { IconButtonModule } from "../icon-button"; @@ -28,20 +29,21 @@ const template = ` Email - + - + `; @Component({ selector: "app-promise-example", template, imports: [ + A11yTitleDirective, AsyncActionsModule, ButtonModule, FormFieldModule, @@ -86,6 +88,7 @@ class PromiseExampleComponent { selector: "app-observable-example", template, imports: [ + A11yTitleDirective, AsyncActionsModule, ButtonModule, FormFieldModule, diff --git a/libs/components/src/async-actions/standalone.mdx b/libs/components/src/async-actions/standalone.mdx index f484ea01c58..a781f40d852 100644 --- a/libs/components/src/async-actions/standalone.mdx +++ b/libs/components/src/async-actions/standalone.mdx @@ -63,7 +63,7 @@ from how click handlers are usually defined with the output syntax `(click)="han ```html -`; +`; ``` ## Stories diff --git a/libs/components/src/async-actions/standalone.stories.ts b/libs/components/src/async-actions/standalone.stories.ts index 1ed6f6c5a59..99cde70566b 100644 --- a/libs/components/src/async-actions/standalone.stories.ts +++ b/libs/components/src/async-actions/standalone.stories.ts @@ -16,7 +16,7 @@ const template = /*html*/ ` - `; + `; @Component({ template, diff --git a/libs/components/src/banner/banner.component.html b/libs/components/src/banner/banner.component.html index 581a56d86cb..bfde8135da9 100644 --- a/libs/components/src/banner/banner.component.html +++ b/libs/components/src/banner/banner.component.html @@ -19,8 +19,7 @@ buttonType="main" size="small" (click)="onClose.emit()" - [attr.title]="'close' | i18n" - [attr.aria-label]="'close' | i18n" + [label]="'close' | i18n" > } diff --git a/libs/components/src/breadcrumbs/breadcrumbs.component.html b/libs/components/src/breadcrumbs/breadcrumbs.component.html index d062e82548e..b63b21de76b 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.component.html +++ b/libs/components/src/breadcrumbs/breadcrumbs.component.html @@ -35,6 +35,7 @@ bitIconButton="bwi-ellipsis-h" [bitMenuTriggerFor]="overflowMenu" size="small" + [label]="'moreBreadcrumbs' | i18n" > @for (breadcrumb of overflow; track breadcrumb) { diff --git a/libs/components/src/breadcrumbs/breadcrumbs.component.ts b/libs/components/src/breadcrumbs/breadcrumbs.component.ts index a1a6e732459..3c24f91be99 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.component.ts +++ b/libs/components/src/breadcrumbs/breadcrumbs.component.ts @@ -2,6 +2,8 @@ import { CommonModule } from "@angular/common"; import { Component, ContentChildren, QueryList, input } from "@angular/core"; import { RouterModule } from "@angular/router"; +import { I18nPipe } from "@bitwarden/ui-common"; + import { IconButtonModule } from "../icon-button"; import { LinkModule } from "../link"; import { MenuModule } from "../menu"; @@ -16,7 +18,7 @@ import { BreadcrumbComponent } from "./breadcrumb.component"; @Component({ selector: "bit-breadcrumbs", templateUrl: "./breadcrumbs.component.html", - imports: [CommonModule, LinkModule, RouterModule, IconButtonModule, MenuModule], + imports: [I18nPipe, CommonModule, LinkModule, RouterModule, IconButtonModule, MenuModule], }) export class BreadcrumbsComponent { readonly show = input(3); diff --git a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts index 98af3c0ae7b..893f645a913 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts +++ b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts @@ -2,9 +2,12 @@ import { Component, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; + import { IconButtonModule } from "../icon-button"; import { LinkModule } from "../link"; import { MenuModule } from "../menu"; +import { I18nMockService } from "../utils"; import { BreadcrumbComponent } from "./breadcrumb.component"; import { BreadcrumbsComponent } from "./breadcrumbs.component"; @@ -26,6 +29,16 @@ export default { decorators: [ moduleMetadata({ imports: [LinkModule, MenuModule, IconButtonModule, RouterModule, BreadcrumbComponent], + providers: [ + { + provide: I18nService, + useFactory: () => { + return new I18nMockService({ + moreBreadcrumbs: "More breadcrumbs", + }); + }, + }, + ], }), applicationConfig({ providers: [ diff --git a/libs/components/src/dialog/dialog/dialog.component.html b/libs/components/src/dialog/dialog/dialog.component.html index 94fc9ef06a0..9f140ca7624 100644 --- a/libs/components/src/dialog/dialog/dialog.component.html +++ b/libs/components/src/dialog/dialog/dialog.component.html @@ -37,8 +37,7 @@ buttonType="main" size="default" bitDialogClose - [attr.title]="'close' | i18n" - [attr.aria-label]="'close' | i18n" + [label]="'close' | i18n" > } diff --git a/libs/components/src/dialog/dialog/dialog.stories.ts b/libs/components/src/dialog/dialog/dialog.stories.ts index 71e07542ed8..f93ef1a2f25 100644 --- a/libs/components/src/dialog/dialog/dialog.stories.ts +++ b/libs/components/src/dialog/dialog/dialog.stories.ts @@ -101,8 +101,7 @@ export const Default: Story = { bitIconButton="bwi-trash" buttonType="danger" size="default" - title="Delete" - aria-label="Delete"> + label="Delete">
`, @@ -219,7 +218,7 @@ export const WithCards: Story = {

Foo

- + @@ -239,7 +238,7 @@ export const WithCards: Story = {

Bar

- + @@ -265,8 +264,7 @@ export const WithCards: Story = { bitIconButton="bwi-trash" buttonType="danger" size="default" - title="Delete" - aria-label="Delete"> + label="Delete"> diff --git a/libs/components/src/disclosure/disclosure.component.ts b/libs/components/src/disclosure/disclosure.component.ts index 703c815087b..2d73d7d8ad6 100644 --- a/libs/components/src/disclosure/disclosure.component.ts +++ b/libs/components/src/disclosure/disclosure.component.ts @@ -28,6 +28,7 @@ let nextId = 0; * bitIconButton="bwi-sliders" * [buttonType]="'muted'" * [bitDisclosureTriggerFor]="disclosureRef" + * [label]="'Settings' | i18n" * > * click button to hide this content * ``` diff --git a/libs/components/src/disclosure/disclosure.stories.ts b/libs/components/src/disclosure/disclosure.stories.ts index bb3680c1f3b..2e45964ccaa 100644 --- a/libs/components/src/disclosure/disclosure.stories.ts +++ b/libs/components/src/disclosure/disclosure.stories.ts @@ -27,7 +27,7 @@ export const DisclosureWithIconButton: Story = { render: (args) => ({ props: args, template: /*html*/ ` - click button to hide this content `, diff --git a/libs/components/src/drawer/drawer-header.component.html b/libs/components/src/drawer/drawer-header.component.html index 863b19edfb2..2723744eda3 100644 --- a/libs/components/src/drawer/drawer-header.component.html +++ b/libs/components/src/drawer/drawer-header.component.html @@ -5,11 +5,5 @@ {{ title() }} - + diff --git a/libs/components/src/form-field/form-field.stories.ts b/libs/components/src/form-field/form-field.stories.ts index e070765ec8a..7aeb2f63040 100644 --- a/libs/components/src/form-field/form-field.stories.ts +++ b/libs/components/src/form-field/form-field.stories.ts @@ -239,8 +239,8 @@ export const Readonly: Story = { Input - - + + @@ -261,7 +261,7 @@ export const Readonly: Story = { Input - + @@ -309,11 +309,11 @@ export const ButtonInputGroup: Story = {
- + - - - + + + `, }), @@ -326,11 +326,11 @@ export const DisabledButtonInputGroup: Story = { template: /*html*/ ` Label - + - - - + + + `, @@ -345,9 +345,9 @@ export const PartiallyDisabledButtonInputGroup: Story = { Label - - - + + + `, }), diff --git a/libs/components/src/form-field/password-input-toggle.spec.ts b/libs/components/src/form-field/password-input-toggle.spec.ts index 95110f2bd93..72f2481d789 100644 --- a/libs/components/src/form-field/password-input-toggle.spec.ts +++ b/libs/components/src/form-field/password-input-toggle.spec.ts @@ -20,7 +20,13 @@ import { BitPasswordInputToggleDirective } from "./password-input-toggle.directi Password - + `, diff --git a/libs/components/src/form-field/password-input-toggle.stories.ts b/libs/components/src/form-field/password-input-toggle.stories.ts index d46ec92ab37..3d50a4eb75a 100644 --- a/libs/components/src/form-field/password-input-toggle.stories.ts +++ b/libs/components/src/form-field/password-input-toggle.stories.ts @@ -48,7 +48,7 @@ export const Default: Story = { Password - + `, @@ -63,7 +63,7 @@ export const Binding: Story = { Password - +