Skip to content

Commit a9b29e8

Browse files
authored
feat: adding missing label props to make text in i18n file customizable (#1980)
* feat: adding label props to make text from i8n file customizable * docs: updating accessibility sections * docs: updating pagination docs * chore: address comments * Create friendly-ants-act.md * Update friendly-ants-act.md * chore: fix constants exports * test: update e2e test * fix: fix vue e2e tests * fix: fix angular e2e tests * chore: revert label updates for country code * chore: fix angular e2e tests
1 parent 26c9bd7 commit a9b29e8

34 files changed

+719
-377
lines changed

.changeset/friendly-ants-act.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@aws-amplify/ui-react": minor
3+
---
4+
5+
feat: adding missing label props to make text in i18n file customizable
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { usePagination, Pagination } from '@aws-amplify/ui-react';
2+
3+
export const PaginationAccessibilityExample = () => {
4+
const paginationProps = usePagination({ totalPages: 5 });
5+
return (
6+
<Pagination
7+
pageLabel="Jump to page"
8+
currentPageLabel="You are on page"
9+
previousLabel="Back to previous page"
10+
nextLabel="Forward to next page"
11+
{...paginationProps}
12+
/>
13+
);
14+
};

docs/src/pages/[platform]/components/pagination/examples/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export { ControlledPaginationExample } from './ControlledPaginationExample';
22
export { DefaultPaginationExample } from './DefaultPaginationExample';
3+
export { PaginationAccessibilityExample } from './PaginationAccessibilityExample';
34
export { PaginationStylingExample } from './PaginationStylingExample';
45
export { PaginationHasMorePagesExample } from './PaginationHasMorePagesExample';
56
export { PaginationSiblingCountExample } from './PaginationSiblingCountExample';

docs/src/pages/[platform]/components/pagination/react.mdx

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ThemeAlert } from '@/components/ThemeAlert';
66
import {
77
ControlledPaginationExample,
88
DefaultPaginationExample,
9+
PaginationAccessibilityExample,
910
PaginationHasMorePagesExample,
1011
PaginationSiblingCountExample,
1112
PaginationStylingExample,
@@ -28,13 +29,15 @@ Import the Pagination component. To use Pagination as an uncontrolled component,
2829
<Example>
2930
<DefaultPaginationExample />
3031
<ExampleCode>
31-
```tsx file=./examples/DefaultPaginationExample.tsx
32+
```tsx file=./examples/DefaultPaginationExample.tsx
33+
34+
```
3235

33-
````
3436
</ExampleCode>
3537
</Example>
3638

3739
### Controlled component
40+
3841
To use Pagination as a controlled component, you'll need to handle state using these callback functions:
3942

4043
- `onNext`: triggered when the next-page button `>` is pressed
@@ -44,9 +47,9 @@ To use Pagination as a controlled component, you'll need to handle state using t
4447
<Example>
4548
<ControlledPaginationExample />
4649
<ExampleCode>
47-
```tsx file=./examples/ControlledPaginationExample.tsx
50+
```tsx file=./examples/ControlledPaginationExample.tsx
4851
49-
````
52+
```
5053

5154
</ExampleCode>
5255
</Example>
@@ -58,9 +61,9 @@ It's common to use a paged API where the total number of pages in the dataset is
5861
<Example>
5962
<PaginationHasMorePagesExample />
6063
<ExampleCode>
61-
```tsx file=./examples/PaginationHasMorePagesExample.tsx
64+
```tsx file=./examples/PaginationHasMorePagesExample.tsx
6265

63-
````
66+
```
6467

6568
</ExampleCode>
6669
</Example>
@@ -72,9 +75,31 @@ It's common to use a paged API where the total number of pages in the dataset is
7275
<Example>
7376
<PaginationSiblingCountExample />
7477
<ExampleCode>
75-
```tsx{8} file=./examples/PaginationSiblingCountExample.tsx
78+
```tsx{7} file=./examples/PaginationSiblingCountExample.tsx
79+
80+
```
81+
82+
</ExampleCode>
83+
</Example>
84+
85+
## Accessibility
86+
87+
By default, the root node of the Pagination component has a role of `navigation`. The previous-page button `<` has `aria-label="Go to previous page"` by default, and likewise, the next-page button `>` has `aria-label=Go to next page`. The current page is labelled by an invisible text [`Current Page:`](https://www.w3.org/WAI/tutorials/menus/structure/#indicate-the-current-item) in conjunction with the current page number (e.g, `Current Page: 1` if page `1` is the current page). Other pages by default have `aria-label=Go to page X`, where `X` is the number of the page. To customize these labels:
88+
89+
- `previousLabel`: Set the `aria-label` for the left arrow button `<` (defaults to `Go to previous page`)
90+
91+
- `nextLabel`: Set the `aria-label` for the right arrow button `>` (defaults to `Go to next page`)
92+
93+
- `currentPageLabel`: Set the invisible label for current page (defaults to `Current Page:`). It will be used to construct the label text for current page. e.g, `Current Page: 1` if page `1` is the current page.
94+
95+
- `pageLabel`: Set the label for each page button other than the current page (defaults to `Go to page`). It will be used to construct the `aria-label`. e.g, `Go to page 1` for page `1` button.
96+
97+
<Example>
98+
<PaginationAccessibilityExample />
99+
<ExampleCode>
100+
```tsx file=./examples/PaginationAccessibilityExample.tsx
76101

77-
````
102+
```
78103

79104
</ExampleCode>
80105
</Example>
@@ -94,9 +119,10 @@ You can customize the appearance of all Pagination components in your applicatio
94119
<Example>
95120
<PaginationThemeExample />
96121
<ExampleCode>
97-
```tsx file=./examples/PaginationThemeExample.tsx
122+
```tsx file=./examples/PaginationThemeExample.tsx
123+
124+
```
98125

99-
````
100126
</ExampleCode>
101127
</Example>
102128

@@ -130,15 +156,6 @@ To override styling on all Pagination components, you can set the Amplify CSS va
130156
</ExampleCode>
131157
</Example>
132158

133-
To replace the Pagination styling, unset it:
134-
135-
```css
136-
.amplify-pagination {
137-
all: unset;
138-
/* Add your styling here*/
139-
}
140-
````
141-
142159
### Local styling
143160

144161
To override styling on a specific Pagination component, you can use a class selector or style props.
@@ -190,7 +207,3 @@ _Using style props:_
190207

191208
</ExampleCode>
192209
</Example>
193-
194-
## Accessibility
195-
196-
By default, the root node of the Pagination component has a role of "navigation", and each page item has an `aria-label` that identifies the purpose of the item ("Go to previous page", "Go to next page", "Go to page 1", etc).

docs/src/pages/[platform]/components/phonenumberfield/examples/AccessibilityExample.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ export const AccessibilityExample = () => (
66
labelHidden={true}
77
defaultCountryCode="+1"
88
placeholder="Phone Number"
9+
countryCodeLabel="Country code"
910
/>
1011
);

packages/react/src/primitives/Collection/Collection.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import { Flex } from '../Flex';
66
import { Grid } from '../Grid';
77
import { Pagination, usePagination } from '../Pagination';
88
import { SearchField } from '../SearchField';
9-
import { ComponentClassNames } from '../shared/constants';
10-
import { SharedText } from '../shared/i18n';
9+
import { ComponentClassNames, ComponentText } from '../shared/constants';
1110
import { strHasLength } from '../shared/utils';
1211
import {
1312
CollectionProps,
@@ -45,6 +44,7 @@ export const Collection = <Item,>({
4544
items,
4645
itemsPerPage = DEFAULT_PAGE_SIZE,
4746
searchFilter = itemHasText,
47+
searchLabel = ComponentText.Collection.searchButtonLabel,
4848
searchPlaceholder,
4949
type = 'list',
5050
testId,
@@ -98,7 +98,7 @@ export const Collection = <Item,>({
9898
{isSearchable ? (
9999
<Flex className={ComponentClassNames.CollectionSearch}>
100100
<SearchField
101-
label={SharedText.Collection.SearchFieldLabel}
101+
label={searchLabel}
102102
placeholder={searchPlaceholder}
103103
onChange={(e) => onSearch(e.target.value)}
104104
onClear={() => setSearchText('')}

packages/react/src/primitives/Collection/__tests__/Collection.test.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,26 @@ describe('Collection component', () => {
200200
userEvent.type(searchInput, text);
201201
expect(searchInput).toHaveValue(text);
202202
});
203+
204+
it('should be able to customize search field label', async () => {
205+
const searchLabel = 'Search emojis';
206+
render(
207+
<Collection
208+
testId={testList}
209+
type="list"
210+
items={emojis}
211+
searchLabel={searchLabel}
212+
isSearchable
213+
>
214+
{(item, index) => (
215+
<div key={index} aria-label={item.title}>
216+
{item.emoji}
217+
</div>
218+
)}
219+
</Collection>
220+
);
221+
222+
const searchControl = await screen.findByLabelText(searchLabel);
223+
expect(searchControl).toBeDefined();
224+
});
203225
});

packages/react/src/primitives/Field/FieldClearButton.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ import * as React from 'react';
33
import { FieldClearButtonProps, Primitive } from '../types';
44
import { FieldGroupIconButton } from '../FieldGroupIcon';
55
import { IconClose } from '../Icon';
6-
import { SharedText } from '../shared/i18n';
6+
import { ComponentText } from '../shared/constants';
77

8-
const ariaLabelText = SharedText.Fields.ariaLabel.clearField;
8+
const ariaLabelText = ComponentText.Fields.clearButtonLabel;
99

1010
const FieldClearButtonPrimitive: Primitive<FieldClearButtonProps, 'button'> = (
11-
props,
11+
{ ariaLabel = ariaLabelText, size, ...rest },
1212
ref
1313
) => (
14-
<FieldGroupIconButton ariaLabel={ariaLabelText} ref={ref} {...props}>
15-
<IconClose size={props.size} />
14+
<FieldGroupIconButton ariaLabel={ariaLabel} ref={ref} {...rest}>
15+
<IconClose size={size} />
1616
</FieldGroupIconButton>
1717
);
1818

packages/react/src/primitives/Pagination/Pagination.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import * as React from 'react';
22
import classNames from 'classnames';
33

4-
import { ComponentClassNames } from '../shared/constants';
54
import { Flex } from '../Flex';
6-
import { PaginationProps, Primitive } from '../types';
7-
import { usePaginationItems } from './usePaginationItems';
85
import { View } from '../View';
6+
import { usePaginationItems } from './usePaginationItems';
7+
import { PaginationProps, Primitive } from '../types';
8+
import { ComponentClassNames } from '../shared/constants';
99

1010
const PaginationPrimitive: Primitive<PaginationProps, 'nav'> = (
1111
{
@@ -14,6 +14,10 @@ const PaginationPrimitive: Primitive<PaginationProps, 'nav'> = (
1414
totalPages,
1515
hasMorePages = false,
1616
siblingCount,
17+
currentPageLabel,
18+
pageLabel,
19+
previousLabel,
20+
nextLabel,
1721
onNext,
1822
onPrevious,
1923
onChange,
@@ -26,6 +30,10 @@ const PaginationPrimitive: Primitive<PaginationProps, 'nav'> = (
2630
totalPages,
2731
hasMorePages,
2832
siblingCount,
33+
currentPageLabel,
34+
pageLabel,
35+
previousLabel,
36+
nextLabel,
2937
onNext,
3038
onPrevious,
3139
onChange

packages/react/src/primitives/Pagination/PaginationItem.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import * as React from 'react';
22
import classNames from 'classnames';
33

4-
import { classNameModifier, classNameModifierByFlag } from '../shared/utils';
54
import { Button } from '../Button';
65
import { Flex } from '../Flex';
76
import { IconChevronLeft, IconChevronRight } from '../Icon';
87
import { View } from '../View';
98
import { VisuallyHidden } from '../VisuallyHidden';
109
import { PaginationItemProps } from '../types/pagination';
11-
import { ComponentClassNames } from '../shared/constants';
10+
import { ComponentClassNames, ComponentText } from '../shared/constants';
11+
import { classNameModifier, classNameModifierByFlag } from '../shared/utils';
1212

1313
export const PAGINATION_CURRENT_TEST_ID = 'current';
1414
export const PAGINATION_ELLIPSIS_TEST_ID = 'ellipsis';
@@ -17,6 +17,7 @@ export const PaginationItem: React.FC<PaginationItemProps> = ({
1717
type,
1818
page,
1919
currentPage,
20+
currentPageLabel = ComponentText.PaginationItem.currentPageLabel,
2021
isDisabled,
2122
onClick,
2223
ariaLabel,
@@ -68,7 +69,7 @@ export const PaginationItem: React.FC<PaginationItemProps> = ({
6869
* Use markup to indicate the current item of a menu, such as the current page on a website, to improve orientation in the menu.
6970
* @link https://www.w3.org/WAI/tutorials/menus/structure/#indicate-the-current-item
7071
*/}
71-
<VisuallyHidden>Current Page:</VisuallyHidden>
72+
<VisuallyHidden>{currentPageLabel}</VisuallyHidden>
7273
{page}
7374
</Flex>
7475
) : (

0 commit comments

Comments
 (0)