diff --git a/src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap b/src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap index f4a10fff93..9e1b448dc9 100644 --- a/src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap +++ b/src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap @@ -2616,6 +2616,7 @@ A \`gridLayout\` is an array of breakpoint definitions. Each definition consists }, { "description": "An object containing all the necessary localized strings required by the component.", + "i18nTag": true, "inlineType": { "name": "AttributeEditorProps.I18nStrings", "properties": [ diff --git a/src/attribute-editor/__tests__/attribute-editor.test.tsx b/src/attribute-editor/__tests__/attribute-editor.test.tsx index 2e48d74656..e8e445c8da 100644 --- a/src/attribute-editor/__tests__/attribute-editor.test.tsx +++ b/src/attribute-editor/__tests__/attribute-editor.test.tsx @@ -620,6 +620,36 @@ describe('Attribute Editor', () => { const wrapper = createWrapper(container).findAttributeEditor()!; expect(wrapper.findRow(1)!.findRemoveButton()!.getElement()).toHaveTextContent('Custom remove'); }); + test('supports providing itemRemovedAriaLive from i18n provider', async () => { + const { container } = render( + + + + ); + const wrapper = createWrapper(container).findAttributeEditor()!; + + wrapper.findRow(1)!.findRemoveButton()!.click(); + + await waitFor(() => + expect(wrapper.find(`[data-testid="removal-announcement"]`)?.getElement()).toHaveTextContent( + 'Custom removal announcement' + ) + ); + }); + test('supports providing itemRemovedAriaLive from i18nStrings prop', async () => { + const { container } = render(); + const wrapper = createWrapper(container).findAttributeEditor()!; + + wrapper.findRow(1)!.findRemoveButton()!.click(); + + await waitFor(() => + expect(wrapper.find(`[data-testid="removal-announcement"]`)?.getElement()).toHaveTextContent( + 'Item removed via prop' + ) + ); + }); }); describe('custom buttons', () => { diff --git a/src/attribute-editor/interfaces.ts b/src/attribute-editor/interfaces.ts index be2aeabb8d..6f29823690 100644 --- a/src/attribute-editor/interfaces.ts +++ b/src/attribute-editor/interfaces.ts @@ -64,8 +64,19 @@ export namespace AttributeEditorProps { // eslint-disable-next-line @typescript-eslint/no-explicit-any export interface I18nStrings { + /** + * Provides a text alternative for the error icon in the error message. + */ errorIconAriaLabel?: string; + + /** + * Provides a text alternative for the warning icon in the warning message. + */ warningIconAriaLabel?: string; + + /** + * Announcement made to screen readers when an item is removed. + */ itemRemovedAriaLive?: string; /** @@ -199,6 +210,7 @@ export interface AttributeEditorProps extends BaseComponentProps { /** * An object containing all the necessary localized strings required by the component. + * @i18n */ i18nStrings?: AttributeEditorProps.I18nStrings; } diff --git a/src/attribute-editor/internal.tsx b/src/attribute-editor/internal.tsx index 8caa901c61..316a6952b3 100644 --- a/src/attribute-editor/internal.tsx +++ b/src/attribute-editor/internal.tsx @@ -7,6 +7,7 @@ import { useMergeRefs, useUniqueId } from '@cloudscape-design/component-toolkit/ import { ButtonProps } from '../button/interfaces'; import { InternalButton } from '../button/internal'; +import { useInternalI18n } from '../i18n/context'; import { getBaseProps } from '../internal/base-component'; import { matchBreakpointMapping } from '../internal/breakpoints'; import { useContainerBreakpoints } from '../internal/hooks/container-queries'; @@ -71,10 +72,16 @@ const InternalAttributeEditor = React.forwardRef( const infoAriaDescribedBy = additionalInfo ? additionalInfoId : undefined; const prevItemsLength = usePrevious(items.length); + const i18n = useInternalI18n('attribute-editor'); React.useEffect(() => { - if (prevItemsLength && prevItemsLength > items.length && i18nStrings?.itemRemovedAriaLive) { - setRemovalAnnouncement(i18nStrings.itemRemovedAriaLive); + if (prevItemsLength && prevItemsLength > items.length) { + const announcement = i18n('i18nStrings.itemRemovedAriaLive', i18nStrings?.itemRemovedAriaLive); + if (announcement) { + setRemovalAnnouncement(announcement); + } else { + setRemovalAnnouncement(''); + } } else { setRemovalAnnouncement(''); } diff --git a/src/i18n/messages-types.ts b/src/i18n/messages-types.ts index 4a837ad86e..4855d00d5c 100644 --- a/src/i18n/messages-types.ts +++ b/src/i18n/messages-types.ts @@ -59,6 +59,7 @@ export interface I18nFormatArgTypes { } "attribute-editor": { "removeButtonText": never; + "i18nStrings.itemRemovedAriaLive": never; } "autosuggest": { "errorIconAriaLabel": never; diff --git a/src/i18n/messages/all.ar.json b/src/i18n/messages/all.ar.json index cc49365d22..25bc8709ea 100644 --- a/src/i18n/messages/all.ar.json +++ b/src/i18n/messages/all.ar.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "المجموع" }, "attribute-editor": { - "removeButtonText": "إزالة" + "removeButtonText": "إزالة", + "i18nStrings.itemRemovedAriaLive": "تمت إزالة العنصر" }, "autosuggest": { "errorIconAriaLabel": "خطأ", diff --git a/src/i18n/messages/all.de.json b/src/i18n/messages/all.de.json index 0c413a1950..7e1322395d 100644 --- a/src/i18n/messages/all.de.json +++ b/src/i18n/messages/all.de.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "Gesamtsumme" }, "attribute-editor": { - "removeButtonText": "Entfernen" + "removeButtonText": "Entfernen", + "i18nStrings.itemRemovedAriaLive": "Artikel wurde entfernt" }, "autosuggest": { "errorIconAriaLabel": "Fehler", diff --git a/src/i18n/messages/all.en-GB.json b/src/i18n/messages/all.en-GB.json index 419f1e67cf..30dac7a51f 100644 --- a/src/i18n/messages/all.en-GB.json +++ b/src/i18n/messages/all.en-GB.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "Total" }, "attribute-editor": { - "removeButtonText": "Remove" + "removeButtonText": "Remove", + "i18nStrings.itemRemovedAriaLive": "Item removed" }, "autosuggest": { "errorIconAriaLabel": "Error", diff --git a/src/i18n/messages/all.en.json b/src/i18n/messages/all.en.json index bfb588f6b7..bb0659f6c3 100644 --- a/src/i18n/messages/all.en.json +++ b/src/i18n/messages/all.en.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "Total" }, "attribute-editor": { - "removeButtonText": "Remove" + "removeButtonText": "Remove", + "i18nStrings.itemRemovedAriaLive": "Item removed" }, "autosuggest": { "errorIconAriaLabel": "Error", diff --git a/src/i18n/messages/all.es.json b/src/i18n/messages/all.es.json index e3465ca8b3..c18d261a8a 100644 --- a/src/i18n/messages/all.es.json +++ b/src/i18n/messages/all.es.json @@ -37,13 +37,14 @@ "ariaLabels.notifications": "Notificaciones", "ariaLabels.tools": "Panel de ayuda", "ariaLabels.toolsClose": "Cerrar el panel de ayuda", - "ariaLabels.toolsToggle": "Abrir panel de ayuda" + "ariaLabels.toolsToggle": "Abrir el panel de ayuda" }, "area-chart": { "i18nStrings.detailTotalLabel": "Total" }, "attribute-editor": { - "removeButtonText": "Eliminar" + "removeButtonText": "Eliminar", + "i18nStrings.itemRemovedAriaLive": "Elemento eliminado" }, "autosuggest": { "errorIconAriaLabel": "Error", diff --git a/src/i18n/messages/all.fr.json b/src/i18n/messages/all.fr.json index 11b4322fb3..2b1365965a 100644 --- a/src/i18n/messages/all.fr.json +++ b/src/i18n/messages/all.fr.json @@ -37,13 +37,14 @@ "ariaLabels.notifications": "Notifications", "ariaLabels.tools": "Volet d'aide", "ariaLabels.toolsClose": "Fermer le volet d'aide", - "ariaLabels.toolsToggle": "Ouvrir le volet d'aide" + "ariaLabels.toolsToggle": "Ouvrir le panneau d’aide" }, "area-chart": { "i18nStrings.detailTotalLabel": "Total" }, "attribute-editor": { - "removeButtonText": "Supprimer" + "removeButtonText": "Supprimer", + "i18nStrings.itemRemovedAriaLive": "Élément supprimé" }, "autosuggest": { "errorIconAriaLabel": "Erreur", diff --git a/src/i18n/messages/all.id.json b/src/i18n/messages/all.id.json index ce9280932c..e2c113b636 100644 --- a/src/i18n/messages/all.id.json +++ b/src/i18n/messages/all.id.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "Total" }, "attribute-editor": { - "removeButtonText": "Hapus" + "removeButtonText": "Hapus", + "i18nStrings.itemRemovedAriaLive": "Item dihapus" }, "autosuggest": { "errorIconAriaLabel": "Kesalahan", @@ -214,7 +215,7 @@ "externalIconAriaLabel": "Buka di tab baru" }, "list": { - "dragHandleAriaLabel": "Seret handel", + "dragHandleAriaLabel": "Handel seret", "dragHandleAriaDescription": "Gunakan Spasi atau Enter untuk mengaktifkan seret pada item, lalu gunakan tombol panah untuk memindahkan posisi item. Untuk menyelesaikan perpindahan posisi, gunakan Spasi atau Enter, atau untuk membatalkan perpindahan, gunakan Escape.", "liveAnnouncementDndStarted": "Mengambil item pada posisi {position} dari {total}", "liveAnnouncementDndDiscarded": "Pengurutan ulang dibatalkan", diff --git a/src/i18n/messages/all.it.json b/src/i18n/messages/all.it.json index 3b1b03a803..20ac2e93c0 100644 --- a/src/i18n/messages/all.it.json +++ b/src/i18n/messages/all.it.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "Totale" }, "attribute-editor": { - "removeButtonText": "Rimuovi" + "removeButtonText": "Rimuovi", + "i18nStrings.itemRemovedAriaLive": "Elemento rimosso" }, "autosuggest": { "errorIconAriaLabel": "Errore", @@ -214,7 +215,7 @@ "externalIconAriaLabel": "Si apre in una nuova scheda" }, "list": { - "dragHandleAriaLabel": "Punto di trascinamento", + "dragHandleAriaLabel": "Maniglia di trascinamento", "dragHandleAriaDescription": "Utilizza Spazio o Invio per attivare il trascinamento di un elemento, quindi usa i tasti freccia per spostare la posizione dell'elemento. Per completare lo spostamento della posizione, utilizza Spazio o Invio oppure per annullare lo spostamento, premi Esc.", "liveAnnouncementDndStarted": "Elemento raccolto nella posizione {position} di {total}", "liveAnnouncementDndDiscarded": "Riordinamento annullato", diff --git a/src/i18n/messages/all.ja.json b/src/i18n/messages/all.ja.json index 40fc2c032b..3e669604b0 100644 --- a/src/i18n/messages/all.ja.json +++ b/src/i18n/messages/all.ja.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "合計" }, "attribute-editor": { - "removeButtonText": "削除" + "removeButtonText": "削除", + "i18nStrings.itemRemovedAriaLive": "アイテムが削除されました" }, "autosuggest": { "errorIconAriaLabel": "エラー", diff --git a/src/i18n/messages/all.ko.json b/src/i18n/messages/all.ko.json index 75e6924a7a..2e6597a78f 100644 --- a/src/i18n/messages/all.ko.json +++ b/src/i18n/messages/all.ko.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "합계" }, "attribute-editor": { - "removeButtonText": "제거" + "removeButtonText": "제거", + "i18nStrings.itemRemovedAriaLive": "항목 제거됨" }, "autosuggest": { "errorIconAriaLabel": "오류", diff --git a/src/i18n/messages/all.pt-BR.json b/src/i18n/messages/all.pt-BR.json index d622a788d1..48b0c5c73f 100644 --- a/src/i18n/messages/all.pt-BR.json +++ b/src/i18n/messages/all.pt-BR.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "Total" }, "attribute-editor": { - "removeButtonText": "Remover" + "removeButtonText": "Remover", + "i18nStrings.itemRemovedAriaLive": "Item removido" }, "autosuggest": { "errorIconAriaLabel": "Erro", diff --git a/src/i18n/messages/all.tr.json b/src/i18n/messages/all.tr.json index fccf22c9c8..ccec17465d 100644 --- a/src/i18n/messages/all.tr.json +++ b/src/i18n/messages/all.tr.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "Toplam" }, "attribute-editor": { - "removeButtonText": "Kaldır" + "removeButtonText": "Kaldır", + "i18nStrings.itemRemovedAriaLive": "Öğe kaldırıldı" }, "autosuggest": { "errorIconAriaLabel": "Hata", diff --git a/src/i18n/messages/all.zh-CN.json b/src/i18n/messages/all.zh-CN.json index a67f601fa2..5d232ce316 100644 --- a/src/i18n/messages/all.zh-CN.json +++ b/src/i18n/messages/all.zh-CN.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "总计" }, "attribute-editor": { - "removeButtonText": "删除" + "removeButtonText": "删除", + "i18nStrings.itemRemovedAriaLive": "项目已移除" }, "autosuggest": { "errorIconAriaLabel": "错误", diff --git a/src/i18n/messages/all.zh-TW.json b/src/i18n/messages/all.zh-TW.json index d18060294f..51dab235d2 100644 --- a/src/i18n/messages/all.zh-TW.json +++ b/src/i18n/messages/all.zh-TW.json @@ -43,7 +43,8 @@ "i18nStrings.detailTotalLabel": "合計" }, "attribute-editor": { - "removeButtonText": "移除" + "removeButtonText": "移除", + "i18nStrings.itemRemovedAriaLive": "項目已移除" }, "autosuggest": { "errorIconAriaLabel": "錯誤",