@atlaskit/media-avatar-picker 26.1.10 → 26.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.agent.md ADDED
@@ -0,0 +1,74 @@
1
+ # Media Avatar Picker - Agent Documentation
2
+
3
+ ## Overview
4
+
5
+ The `@atlaskit/media-avatar-picker` package provides components for selecting, uploading, and
6
+ cropping avatar images. It includes both local image upload functionality and predefined avatar
7
+ selection.
8
+
9
+ ## Key Components
10
+
11
+ ### AvatarPickerDialog
12
+
13
+ Main dialog component that orchestrates the avatar selection experience.
14
+
15
+ ### ImageCropper
16
+
17
+ Interactive component for cropping uploaded images with keyboard and mouse support.
18
+
19
+ ### ImageNavigator
20
+
21
+ Component that handles image upload, display, and basic navigation controls.
22
+
23
+ ## Accessibility Features
24
+
25
+ ### Image Cropper Accessibility
26
+
27
+ The image cropper component has been designed with accessibility in mind:
28
+
29
+ - **Keyboard Navigation**: Users can navigate and crop images using arrow keys
30
+ - **Screen Reader Support**: Proper ARIA labels and roles for assistive technologies
31
+ - **Focus Management**: Clear focus indicators and logical tab order
32
+ - **Live Announcements**: Real-time feedback for image movements via aria-live regions
33
+
34
+ #### Recent Accessibility Improvements (2025)
35
+
36
+ - Fixed `aria-prohibited-attr` violation by adding `role="button"` to interactive cropping mask
37
+ elements
38
+ - Ensured proper semantic meaning for focusable elements with ARIA labels
39
+ - Maintains WCAG Level A compliance
40
+
41
+ ### Implementation Details
42
+
43
+ The image cropper mask elements use:
44
+
45
+ - `role="button"` - Identifies the element as an interactive button
46
+ - `tabIndex={0}` - Makes the element focusable via keyboard
47
+ - `aria-label` - Provides descriptive text for screen readers
48
+ - `onKeyDown` - Handles arrow key navigation for image positioning
49
+
50
+ ## Testing
51
+
52
+ - All accessibility tests pass with zero violations
53
+ - Comprehensive keyboard navigation testing
54
+ - Screen reader compatibility verified
55
+ - Visual regression tests for different image orientations
56
+
57
+ ## Known Limitations
58
+
59
+ - Only supports image/gif, image/jpeg, and image/png formats
60
+ - Maximum file size of 10MB
61
+ - SVG format not currently supported
62
+
63
+ ## Recent Changes
64
+
65
+ - **2025-01**: Fixed accessibility violations in image cropper component
66
+ - Enhanced ARIA support for better screen reader experience
67
+ - Updated tests to reflect accessibility improvements
68
+
69
+ ## Development Notes
70
+
71
+ - Follow WCAG guidelines when making changes to interactive elements
72
+ - Run accessibility tests before submitting changes
73
+ - Consider keyboard-only users when adding new features
74
+ - Ensure proper ARIA attributes for any new focusable elements
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @atlaskit/media-avatar-picker
2
2
 
3
+ ## 26.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#192283](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/192283)
8
+ [`7caa838fc933e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7caa838fc933e) -
9
+ fixing some ts typecheck errors
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
15
+ ## 26.1.11
16
+
17
+ ### Patch Changes
18
+
19
+ - [#192828](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/192828)
20
+ [`a798dd56b4aba`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a798dd56b4aba) -
21
+ Fixes A11Y issues
22
+
3
23
  ## 26.1.10
4
24
 
5
25
  ### Patch Changes
package/README.md CHANGED
@@ -43,6 +43,26 @@ The component will handle the following errors on the client:
43
43
 
44
44
  See the `errorMessage` property below to set your own custom error message if required.
45
45
 
46
+ ## Accessibility
47
+
48
+ This component is designed to be fully accessible and follows WCAG guidelines:
49
+
50
+ ### Keyboard Navigation
51
+ - **Image Cropping**: Use arrow keys to move and position the image within the crop area
52
+ - **Tab Navigation**: All interactive elements are accessible via keyboard
53
+ - **Focus Management**: Clear visual focus indicators throughout the interface
54
+
55
+ ### Screen Reader Support
56
+ - **ARIA Labels**: Descriptive labels for all interactive elements
57
+ - **Live Announcements**: Real-time feedback when moving images during cropping
58
+ - **Semantic Markup**: Proper roles and structure for assistive technologies
59
+
60
+ ### Features
61
+ - Fully keyboard accessible image cropping and navigation
62
+ - Screen reader announcements for image positioning
63
+ - High contrast focus indicators
64
+ - Logical tab order throughout the interface
65
+
46
66
  ## API
47
67
 
48
68
  `onImagePicked?: (file: File, crop: CropProperties) => void`
@@ -134,7 +134,7 @@ var AvatarPickerDialog = exports.AvatarPickerDialog = /*#__PURE__*/function (_Pu
134
134
  * Initialised with no-op function. Is assigned cropped image exporting
135
135
  * function when internal ImageCropper mounts via this.onImageNavigatorLoad
136
136
  */
137
- (0, _defineProperty2.default)(_this, "exportCroppedImage", function (outputSize) {
137
+ (0, _defineProperty2.default)(_this, "exportCroppedImage", function (_outputSize) {
138
138
  return '';
139
139
  });
140
140
  (0, _defineProperty2.default)(_this, "onSave", function (event) {
@@ -195,6 +195,7 @@ var ImageCropper = exports.ImageCropper = /*#__PURE__*/function (_Component) {
195
195
  style: maskStyles,
196
196
  tabIndex: 0,
197
197
  onKeyDown: this.onKeyDown,
198
+ role: "button",
198
199
  "aria-label": formatMessage(_mediaUi.messages.image_cropper_arrow_keys_label)
199
200
  }) : /*#__PURE__*/_react.default.createElement(_compiled.Box, {
200
201
  testId: "image-cropper-mask",
@@ -204,6 +205,7 @@ var ImageCropper = exports.ImageCropper = /*#__PURE__*/function (_Component) {
204
205
  style: maskStyles,
205
206
  tabIndex: 0,
206
207
  onKeyDown: this.onKeyDown,
208
+ role: "button",
207
209
  "aria-label": formatMessage(_mediaUi.messages.image_cropper_arrow_keys_label)
208
210
  }), /*#__PURE__*/_react.default.createElement(_compiled.Box, {
209
211
  id: "drag-overlay",
@@ -96,7 +96,7 @@ export class AvatarPickerDialog extends PureComponent {
96
96
  * Initialised with no-op function. Is assigned cropped image exporting
97
97
  * function when internal ImageCropper mounts via this.onImageNavigatorLoad
98
98
  */
99
- _defineProperty(this, "exportCroppedImage", outputSize => '');
99
+ _defineProperty(this, "exportCroppedImage", _outputSize => '');
100
100
  _defineProperty(this, "onSave", event => {
101
101
  event.preventDefault();
102
102
  const {
@@ -180,6 +180,7 @@ export class ImageCropper extends Component {
180
180
  style: maskStyles,
181
181
  tabIndex: 0,
182
182
  onKeyDown: this.onKeyDown,
183
+ role: "button",
183
184
  "aria-label": formatMessage(messages.image_cropper_arrow_keys_label)
184
185
  }) : /*#__PURE__*/React.createElement(Box, {
185
186
  testId: "image-cropper-mask",
@@ -189,6 +190,7 @@ export class ImageCropper extends Component {
189
190
  style: maskStyles,
190
191
  tabIndex: 0,
191
192
  onKeyDown: this.onKeyDown,
193
+ role: "button",
192
194
  "aria-label": formatMessage(messages.image_cropper_arrow_keys_label)
193
195
  }), /*#__PURE__*/React.createElement(Box, {
194
196
  id: "drag-overlay",
@@ -127,7 +127,7 @@ export var AvatarPickerDialog = /*#__PURE__*/function (_PureComponent) {
127
127
  * Initialised with no-op function. Is assigned cropped image exporting
128
128
  * function when internal ImageCropper mounts via this.onImageNavigatorLoad
129
129
  */
130
- _defineProperty(_this, "exportCroppedImage", function (outputSize) {
130
+ _defineProperty(_this, "exportCroppedImage", function (_outputSize) {
131
131
  return '';
132
132
  });
133
133
  _defineProperty(_this, "onSave", function (event) {
@@ -187,6 +187,7 @@ export var ImageCropper = /*#__PURE__*/function (_Component) {
187
187
  style: maskStyles,
188
188
  tabIndex: 0,
189
189
  onKeyDown: this.onKeyDown,
190
+ role: "button",
190
191
  "aria-label": formatMessage(messages.image_cropper_arrow_keys_label)
191
192
  }) : /*#__PURE__*/React.createElement(Box, {
192
193
  testId: "image-cropper-mask",
@@ -196,6 +197,7 @@ export var ImageCropper = /*#__PURE__*/function (_Component) {
196
197
  style: maskStyles,
197
198
  tabIndex: 0,
198
199
  onKeyDown: this.onKeyDown,
200
+ role: "button",
199
201
  "aria-label": formatMessage(messages.image_cropper_arrow_keys_label)
200
202
  }), /*#__PURE__*/React.createElement(Box, {
201
203
  id: "drag-overlay",
@@ -30,7 +30,7 @@ export declare class AvatarPickerDialog extends PureComponent<AvatarPickerDialog
30
30
  * Initialised with no-op function. Is assigned cropped image exporting
31
31
  * function when internal ImageCropper mounts via this.onImageNavigatorLoad
32
32
  */
33
- exportCroppedImage: (outputSize?: number) => string;
33
+ exportCroppedImage: (_outputSize?: number) => string;
34
34
  onSave: (event: React.FormEvent<HTMLFormElement>) => void;
35
35
  onShowMore: () => void;
36
36
  onGoBack: () => void;
@@ -30,7 +30,7 @@ export declare class AvatarPickerDialog extends PureComponent<AvatarPickerDialog
30
30
  * Initialised with no-op function. Is assigned cropped image exporting
31
31
  * function when internal ImageCropper mounts via this.onImageNavigatorLoad
32
32
  */
33
- exportCroppedImage: (outputSize?: number) => string;
33
+ exportCroppedImage: (_outputSize?: number) => string;
34
34
  onSave: (event: React.FormEvent<HTMLFormElement>) => void;
35
35
  onShowMore: () => void;
36
36
  onGoBack: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/media-avatar-picker",
3
- "version": "26.1.10",
3
+ "version": "26.2.0",
4
4
  "description": "A component to select, drag and resize image avatars. It also provides a default list of predefined avatars.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -38,11 +38,11 @@
38
38
  "@atlaskit/css": "^0.12.0",
39
39
  "@atlaskit/flag": "^17.3.0",
40
40
  "@atlaskit/form": "^12.0.0",
41
- "@atlaskit/icon": "^27.7.0",
41
+ "@atlaskit/icon": "^27.8.0",
42
42
  "@atlaskit/media-ui": "^28.6.0",
43
43
  "@atlaskit/modal-dialog": "^14.3.0",
44
- "@atlaskit/primitives": "^14.10.0",
45
- "@atlaskit/range": "^9.1.0",
44
+ "@atlaskit/primitives": "^14.11.0",
45
+ "@atlaskit/range": "^9.2.0",
46
46
  "@atlaskit/spinner": "^19.0.0",
47
47
  "@atlaskit/textfield": "^8.0.0",
48
48
  "@atlaskit/theme": "^19.0.0",