@atlaskit/avatar 25.7.5 → 25.8.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/avatar
2
2
 
3
+ ## 25.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 25.8.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`7140aa6f03a00`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7140aa6f03a00) -
14
+ Adds aria-controls, aria-expanded, and aria-haspopup props to Avatar, enabling it to be used
15
+ directly as a popup trigger without needing an external button wrapper.
16
+
3
17
  ## 25.7.5
4
18
 
5
19
  ### Patch Changes
@@ -84,12 +84,18 @@ var AvatarContent = exports.AvatarContent = /*#__PURE__*/(0, _react.forwardRef)(
84
84
  target = _useAvatarContent.target,
85
85
  testId = _useAvatarContent.testId,
86
86
  size = _useAvatarContent.size,
87
- stackIndex = _useAvatarContent.stackIndex;
88
- var isInteractive = Boolean(onClick || href || isDisabled);
87
+ stackIndex = _useAvatarContent.stackIndex,
88
+ ariaControls = _useAvatarContent['aria-controls'],
89
+ ariaExpanded = _useAvatarContent['aria-expanded'],
90
+ ariaHasPopup = _useAvatarContent['aria-haspopup'];
91
+ var isInteractive = Boolean(onClick || href || isDisabled || ariaHasPopup);
89
92
  var renderedContent = /*#__PURE__*/React.createElement(Container, (0, _extends2.default)({
90
93
  style: (0, _defineProperty2.default)((0, _defineProperty2.default)({}, bgColorCssVar, borderColor), boxShadowCssVar, "0 0 0 2px ".concat(borderColor)),
91
94
  ref: ref || contextRef,
92
95
  "aria-label": isInteractive ? label : undefined,
96
+ "aria-controls": ariaControls,
97
+ "aria-expanded": ariaExpanded,
98
+ "aria-haspopup": ariaHasPopup,
93
99
  onClick: onClick,
94
100
  tabIndex: tabIndex,
95
101
  "data-testid": testId,
@@ -60,7 +60,10 @@ var Avatar = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
60
60
  AvatarContainer = _ref$as === void 0 ? 'div' : _ref$as,
61
61
  _ref$isDecorative = _ref.isDecorative,
62
62
  isDecorative = _ref$isDecorative === void 0 ? false : _ref$isDecorative,
63
- imgLoading = _ref.imgLoading;
63
+ imgLoading = _ref.imgLoading,
64
+ ariaControls = _ref['aria-controls'],
65
+ ariaExpanded = _ref['aria-expanded'],
66
+ ariaHasPopup = _ref['aria-haspopup'];
64
67
  var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
65
68
  createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
66
69
  var context = (0, _context.useAvatarContext)();
@@ -113,7 +116,7 @@ var Avatar = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
113
116
  // add presence or status to the label by default if presence and status are passed as a string
114
117
  // if status or presence are nodes this is not added to the label by default
115
118
  var defaultLabel = [name, isStatus && !customStatusNode && "(".concat(status, ")"), isPresence && !customPresenceNode && "(".concat(presence, ")")].filter(Boolean).join(' ');
116
- var isInteractive = onClick || href || isDisabled;
119
+ var isInteractive = onClick || href || isDisabled || ariaHasPopup;
117
120
  var containerShouldBeImage = Boolean(!isInteractive && defaultLabel);
118
121
  return /*#__PURE__*/React.createElement(_context.EnsureIsInsideAvatarContext.Provider, {
119
122
  value: true
@@ -127,7 +130,7 @@ var Avatar = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
127
130
  className: (0, _runtime.ax)(["_12ji1r31 _1qu2glyw _12y3idpf _1e0c1o8l _kqswh2mm"])
128
131
  }, /*#__PURE__*/React.createElement(_context.AvatarContentContext.Provider, {
129
132
  value: {
130
- as: (0, _utilities.getCustomElement)(isDisabled, href, onClick),
133
+ as: (0, _utilities.getCustomElement)(isDisabled, href, onClick, ariaHasPopup),
131
134
  appearance: appearance,
132
135
  borderColor: borderColor,
133
136
  href: href,
@@ -139,6 +142,9 @@ var Avatar = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
139
142
  stackIndex: stackIndex,
140
143
  target: target,
141
144
  testId: testId ? "".concat(testId, "--inner") : undefined,
145
+ 'aria-controls': ariaControls,
146
+ 'aria-expanded': ariaExpanded,
147
+ 'aria-haspopup': ariaHasPopup,
142
148
  avatarImage: /*#__PURE__*/React.createElement(_avatarImage.default, {
143
149
  alt: !containerShouldBeImage && src ? name : undefined,
144
150
  src: src,
@@ -5,11 +5,11 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getAppearanceForAppType = getAppearanceForAppType;
7
7
  exports.getCustomElement = void 0;
8
- var getCustomElement = exports.getCustomElement = function getCustomElement(isDisabled, href, onClick) {
8
+ var getCustomElement = exports.getCustomElement = function getCustomElement(isDisabled, href, onClick, ariaHasPopup) {
9
9
  if (href && !isDisabled) {
10
10
  return 'a';
11
11
  }
12
- if (onClick || isDisabled) {
12
+ if (onClick || isDisabled || ariaHasPopup) {
13
13
  return 'button';
14
14
  }
15
15
  return 'span';
@@ -74,9 +74,12 @@ export const AvatarContent = /*#__PURE__*/forwardRef(({
74
74
  target,
75
75
  testId,
76
76
  size,
77
- stackIndex
77
+ stackIndex,
78
+ 'aria-controls': ariaControls,
79
+ 'aria-expanded': ariaExpanded,
80
+ 'aria-haspopup': ariaHasPopup
78
81
  } = useAvatarContent();
79
- const isInteractive = Boolean(onClick || href || isDisabled);
82
+ const isInteractive = Boolean(onClick || href || isDisabled || ariaHasPopup);
80
83
  const renderedContent = /*#__PURE__*/React.createElement(Container, _extends({
81
84
  style: {
82
85
  [bgColorCssVar]: borderColor,
@@ -84,6 +87,9 @@ export const AvatarContent = /*#__PURE__*/forwardRef(({
84
87
  },
85
88
  ref: ref || contextRef,
86
89
  "aria-label": isInteractive ? label : undefined,
90
+ "aria-controls": ariaControls,
91
+ "aria-expanded": ariaExpanded,
92
+ "aria-haspopup": ariaHasPopup,
87
93
  onClick: onClick,
88
94
  tabIndex: tabIndex,
89
95
  "data-testid": testId,
@@ -45,7 +45,10 @@ const Avatar = /*#__PURE__*/forwardRef(({
45
45
  testId,
46
46
  as: AvatarContainer = 'div',
47
47
  isDecorative = false,
48
- imgLoading
48
+ imgLoading,
49
+ 'aria-controls': ariaControls,
50
+ 'aria-expanded': ariaExpanded,
51
+ 'aria-haspopup': ariaHasPopup
49
52
  }, ref) => {
50
53
  const {
51
54
  createAnalyticsEvent
@@ -101,7 +104,7 @@ const Avatar = /*#__PURE__*/forwardRef(({
101
104
  // add presence or status to the label by default if presence and status are passed as a string
102
105
  // if status or presence are nodes this is not added to the label by default
103
106
  const defaultLabel = [name, isStatus && !customStatusNode && `(${status})`, isPresence && !customPresenceNode && `(${presence})`].filter(Boolean).join(' ');
104
- const isInteractive = onClick || href || isDisabled;
107
+ const isInteractive = onClick || href || isDisabled || ariaHasPopup;
105
108
  const containerShouldBeImage = Boolean(!isInteractive && defaultLabel);
106
109
  return /*#__PURE__*/React.createElement(EnsureIsInsideAvatarContext.Provider, {
107
110
  value: true
@@ -115,7 +118,7 @@ const Avatar = /*#__PURE__*/forwardRef(({
115
118
  className: ax(["_12ji1r31 _1qu2glyw _12y3idpf _1e0c1o8l _kqswh2mm"])
116
119
  }, /*#__PURE__*/React.createElement(AvatarContentContext.Provider, {
117
120
  value: {
118
- as: getCustomElement(isDisabled, href, onClick),
121
+ as: getCustomElement(isDisabled, href, onClick, ariaHasPopup),
119
122
  appearance,
120
123
  borderColor,
121
124
  href,
@@ -127,6 +130,9 @@ const Avatar = /*#__PURE__*/forwardRef(({
127
130
  stackIndex,
128
131
  target,
129
132
  testId: testId ? `${testId}--inner` : undefined,
133
+ 'aria-controls': ariaControls,
134
+ 'aria-expanded': ariaExpanded,
135
+ 'aria-haspopup': ariaHasPopup,
130
136
  avatarImage: /*#__PURE__*/React.createElement(AvatarImage, {
131
137
  alt: !containerShouldBeImage && src ? name : undefined,
132
138
  src: src,
@@ -1,8 +1,8 @@
1
- export const getCustomElement = (isDisabled, href, onClick) => {
1
+ export const getCustomElement = (isDisabled, href, onClick, ariaHasPopup) => {
2
2
  if (href && !isDisabled) {
3
3
  return 'a';
4
4
  }
5
- if (onClick || isDisabled) {
5
+ if (onClick || isDisabled || ariaHasPopup) {
6
6
  return 'button';
7
7
  }
8
8
  return 'span';
@@ -75,12 +75,18 @@ export var AvatarContent = /*#__PURE__*/forwardRef(function (_ref, ref) {
75
75
  target = _useAvatarContent.target,
76
76
  testId = _useAvatarContent.testId,
77
77
  size = _useAvatarContent.size,
78
- stackIndex = _useAvatarContent.stackIndex;
79
- var isInteractive = Boolean(onClick || href || isDisabled);
78
+ stackIndex = _useAvatarContent.stackIndex,
79
+ ariaControls = _useAvatarContent['aria-controls'],
80
+ ariaExpanded = _useAvatarContent['aria-expanded'],
81
+ ariaHasPopup = _useAvatarContent['aria-haspopup'];
82
+ var isInteractive = Boolean(onClick || href || isDisabled || ariaHasPopup);
80
83
  var renderedContent = /*#__PURE__*/React.createElement(Container, _extends({
81
84
  style: _defineProperty(_defineProperty({}, bgColorCssVar, borderColor), boxShadowCssVar, "0 0 0 2px ".concat(borderColor)),
82
85
  ref: ref || contextRef,
83
86
  "aria-label": isInteractive ? label : undefined,
87
+ "aria-controls": ariaControls,
88
+ "aria-expanded": ariaExpanded,
89
+ "aria-haspopup": ariaHasPopup,
84
90
  onClick: onClick,
85
91
  tabIndex: tabIndex,
86
92
  "data-testid": testId,
@@ -51,7 +51,10 @@ var Avatar = /*#__PURE__*/forwardRef(function (_ref, ref) {
51
51
  AvatarContainer = _ref$as === void 0 ? 'div' : _ref$as,
52
52
  _ref$isDecorative = _ref.isDecorative,
53
53
  isDecorative = _ref$isDecorative === void 0 ? false : _ref$isDecorative,
54
- imgLoading = _ref.imgLoading;
54
+ imgLoading = _ref.imgLoading,
55
+ ariaControls = _ref['aria-controls'],
56
+ ariaExpanded = _ref['aria-expanded'],
57
+ ariaHasPopup = _ref['aria-haspopup'];
55
58
  var _useAnalyticsEvents = useAnalyticsEvents(),
56
59
  createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
57
60
  var context = useAvatarContext();
@@ -104,7 +107,7 @@ var Avatar = /*#__PURE__*/forwardRef(function (_ref, ref) {
104
107
  // add presence or status to the label by default if presence and status are passed as a string
105
108
  // if status or presence are nodes this is not added to the label by default
106
109
  var defaultLabel = [name, isStatus && !customStatusNode && "(".concat(status, ")"), isPresence && !customPresenceNode && "(".concat(presence, ")")].filter(Boolean).join(' ');
107
- var isInteractive = onClick || href || isDisabled;
110
+ var isInteractive = onClick || href || isDisabled || ariaHasPopup;
108
111
  var containerShouldBeImage = Boolean(!isInteractive && defaultLabel);
109
112
  return /*#__PURE__*/React.createElement(EnsureIsInsideAvatarContext.Provider, {
110
113
  value: true
@@ -118,7 +121,7 @@ var Avatar = /*#__PURE__*/forwardRef(function (_ref, ref) {
118
121
  className: ax(["_12ji1r31 _1qu2glyw _12y3idpf _1e0c1o8l _kqswh2mm"])
119
122
  }, /*#__PURE__*/React.createElement(AvatarContentContext.Provider, {
120
123
  value: {
121
- as: getCustomElement(isDisabled, href, onClick),
124
+ as: getCustomElement(isDisabled, href, onClick, ariaHasPopup),
122
125
  appearance: appearance,
123
126
  borderColor: borderColor,
124
127
  href: href,
@@ -130,6 +133,9 @@ var Avatar = /*#__PURE__*/forwardRef(function (_ref, ref) {
130
133
  stackIndex: stackIndex,
131
134
  target: target,
132
135
  testId: testId ? "".concat(testId, "--inner") : undefined,
136
+ 'aria-controls': ariaControls,
137
+ 'aria-expanded': ariaExpanded,
138
+ 'aria-haspopup': ariaHasPopup,
133
139
  avatarImage: /*#__PURE__*/React.createElement(AvatarImage, {
134
140
  alt: !containerShouldBeImage && src ? name : undefined,
135
141
  src: src,
@@ -1,8 +1,8 @@
1
- export var getCustomElement = function getCustomElement(isDisabled, href, onClick) {
1
+ export var getCustomElement = function getCustomElement(isDisabled, href, onClick, ariaHasPopup) {
2
2
  if (href && !isDisabled) {
3
3
  return 'a';
4
4
  }
5
- if (onClick || isDisabled) {
5
+ if (onClick || isDisabled || ariaHasPopup) {
6
6
  return 'button';
7
7
  }
8
8
  return 'span';
@@ -98,6 +98,20 @@ export interface AvatarPropTypes {
98
98
  * Defines the loading behaviour of the avatar image. Default value is eager.
99
99
  */
100
100
  imgLoading?: 'lazy' | 'eager';
101
+ /**
102
+ * Identifies the popup element that the avatar controls.
103
+ * Used when Avatar is a trigger for a popup.
104
+ */
105
+ 'aria-controls'?: string;
106
+ /**
107
+ * Announces to assistive technology whether the controlled popup is currently open or closed.
108
+ */
109
+ 'aria-expanded'?: boolean;
110
+ /**
111
+ * Informs assistive technology that this element triggers a popup.
112
+ * When set, Avatar will render as a `<button>` element even without `onClick`.
113
+ */
114
+ 'aria-haspopup'?: boolean | 'dialog';
101
115
  }
102
116
  /**
103
117
  * __Avatar__
@@ -16,7 +16,7 @@ export type AvatarContextProps = {
16
16
  * </AvatarContext.Provider>
17
17
  * ```
18
18
  */
19
- export declare const AvatarContext: import("react").Context<AvatarContextProps | undefined>;
19
+ export declare const AvatarContext: import('react').Context<AvatarContextProps | undefined>;
20
20
  export declare const useAvatarContext: () => AvatarContextProps | undefined;
21
21
  type AvatarContentContextProps = {
22
22
  as: 'a' | 'button' | 'span';
@@ -33,6 +33,9 @@ type AvatarContentContextProps = {
33
33
  testId?: string;
34
34
  size: SizeType;
35
35
  stackIndex?: number;
36
+ 'aria-controls'?: string;
37
+ 'aria-expanded'?: boolean;
38
+ 'aria-haspopup'?: boolean | 'dialog';
36
39
  };
37
40
  /**
38
41
  * __Avatar content context__
@@ -40,12 +43,12 @@ type AvatarContentContextProps = {
40
43
  * This context provides the props for the AvatarContent component, enabling
41
44
  * consumers to compose the AvatarContent with the Avatar component.
42
45
  */
43
- export declare const AvatarContentContext: import("react").Context<AvatarContentContextProps>;
46
+ export declare const AvatarContentContext: import('react').Context<AvatarContentContextProps>;
44
47
  export declare const useAvatarContent: () => AvatarContentContextProps;
45
48
  /**
46
49
  * Used to ensure Avatar sub-components are used within a Avatar component,
47
50
  * and provide a useful error message if not.
48
51
  */
49
- export declare const EnsureIsInsideAvatarContext: import("react").Context<boolean>;
52
+ export declare const EnsureIsInsideAvatarContext: import('react').Context<boolean>;
50
53
  export declare const useEnsureIsInsideAvatar: () => void;
51
54
  export {};
@@ -1,4 +1,4 @@
1
1
  import { type MouseEventHandler } from 'react';
2
2
  import type { AppearanceType } from './types';
3
- export declare const getCustomElement: (isDisabled?: boolean, href?: string, onClick?: MouseEventHandler) => "a" | "button" | "span";
3
+ export declare const getCustomElement: (isDisabled?: boolean, href?: string, onClick?: MouseEventHandler, ariaHasPopup?: boolean | 'dialog') => 'a' | 'button' | 'span';
4
4
  export declare function getAppearanceForAppType(appType: string | null | undefined): AppearanceType;
@@ -98,6 +98,20 @@ export interface AvatarPropTypes {
98
98
  * Defines the loading behaviour of the avatar image. Default value is eager.
99
99
  */
100
100
  imgLoading?: 'lazy' | 'eager';
101
+ /**
102
+ * Identifies the popup element that the avatar controls.
103
+ * Used when Avatar is a trigger for a popup.
104
+ */
105
+ 'aria-controls'?: string;
106
+ /**
107
+ * Announces to assistive technology whether the controlled popup is currently open or closed.
108
+ */
109
+ 'aria-expanded'?: boolean;
110
+ /**
111
+ * Informs assistive technology that this element triggers a popup.
112
+ * When set, Avatar will render as a `<button>` element even without `onClick`.
113
+ */
114
+ 'aria-haspopup'?: boolean | 'dialog';
101
115
  }
102
116
  /**
103
117
  * __Avatar__
@@ -16,7 +16,7 @@ export type AvatarContextProps = {
16
16
  * </AvatarContext.Provider>
17
17
  * ```
18
18
  */
19
- export declare const AvatarContext: import("react").Context<AvatarContextProps | undefined>;
19
+ export declare const AvatarContext: import('react').Context<AvatarContextProps | undefined>;
20
20
  export declare const useAvatarContext: () => AvatarContextProps | undefined;
21
21
  type AvatarContentContextProps = {
22
22
  as: 'a' | 'button' | 'span';
@@ -33,6 +33,9 @@ type AvatarContentContextProps = {
33
33
  testId?: string;
34
34
  size: SizeType;
35
35
  stackIndex?: number;
36
+ 'aria-controls'?: string;
37
+ 'aria-expanded'?: boolean;
38
+ 'aria-haspopup'?: boolean | 'dialog';
36
39
  };
37
40
  /**
38
41
  * __Avatar content context__
@@ -40,12 +43,12 @@ type AvatarContentContextProps = {
40
43
  * This context provides the props for the AvatarContent component, enabling
41
44
  * consumers to compose the AvatarContent with the Avatar component.
42
45
  */
43
- export declare const AvatarContentContext: import("react").Context<AvatarContentContextProps>;
46
+ export declare const AvatarContentContext: import('react').Context<AvatarContentContextProps>;
44
47
  export declare const useAvatarContent: () => AvatarContentContextProps;
45
48
  /**
46
49
  * Used to ensure Avatar sub-components are used within a Avatar component,
47
50
  * and provide a useful error message if not.
48
51
  */
49
- export declare const EnsureIsInsideAvatarContext: import("react").Context<boolean>;
52
+ export declare const EnsureIsInsideAvatarContext: import('react').Context<boolean>;
50
53
  export declare const useEnsureIsInsideAvatar: () => void;
51
54
  export {};
@@ -1,4 +1,4 @@
1
1
  import { type MouseEventHandler } from 'react';
2
2
  import type { AppearanceType } from './types';
3
- export declare const getCustomElement: (isDisabled?: boolean, href?: string, onClick?: MouseEventHandler) => "a" | "button" | "span";
3
+ export declare const getCustomElement: (isDisabled?: boolean, href?: string, onClick?: MouseEventHandler, ariaHasPopup?: boolean | 'dialog') => 'a' | 'button' | 'span';
4
4
  export declare function getAppearanceForAppType(appType: string | null | undefined): AppearanceType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/avatar",
3
- "version": "25.7.5",
3
+ "version": "25.8.1",
4
4
  "description": "An avatar is a visual representation of a user or entity.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -35,7 +35,7 @@
35
35
  "@atlaskit/analytics-next": "^11.1.0",
36
36
  "@atlaskit/css": "^0.19.0",
37
37
  "@atlaskit/ds-lib": "^5.3.0",
38
- "@atlaskit/icon": "^31.0.0",
38
+ "@atlaskit/icon": "^32.0.0",
39
39
  "@atlaskit/platform-feature-flags": "^1.1.0",
40
40
  "@atlaskit/primitives": "^18.0.0",
41
41
  "@atlaskit/theme": "^21.0.0",
@@ -52,7 +52,7 @@
52
52
  "@af/visual-regression": "workspace:^",
53
53
  "@atlaskit/button": "^23.9.0",
54
54
  "@atlaskit/code": "^17.4.0",
55
- "@atlaskit/docs": "^11.3.0",
55
+ "@atlaskit/docs": "^11.4.0",
56
56
  "@atlaskit/form": "^15.3.0",
57
57
  "@atlaskit/heading": "^5.3.0",
58
58
  "@atlaskit/link": "^3.3.0",
@@ -96,9 +96,6 @@
96
96
  "platform.design-system-team.avatar-item-font-size_830x6": {
97
97
  "type": "boolean"
98
98
  },
99
- "platform-visual-refresh-icons": {
100
- "type": "boolean"
101
- },
102
99
  "platform_dst_avatar_tile": {
103
100
  "type": "boolean"
104
101
  },