@atlaskit/react-select 1.1.0 → 1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @atlaskit/react-select
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#157818](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/157818)
8
+ [`87c14ad1a3efa`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/87c14ad1a3efa) -
9
+ Use semantic tags and arias for combobox and listbox and reduce aria-live
10
+
3
11
  ## 1.1.0
4
12
 
5
13
  ### Minor Changes
@@ -8,6 +8,7 @@ exports.isIOS = isIOS;
8
8
  exports.isIPad = isIPad;
9
9
  exports.isIPhone = isIPhone;
10
10
  exports.isMac = isMac;
11
+ exports.isSafari = isSafari;
11
12
  function testPlatform(re) {
12
13
  var _window$navigator$use;
13
14
  return typeof window !== 'undefined' && window.navigator != null ?
@@ -17,6 +18,10 @@ function testPlatform(re) {
17
18
  function isIPhone() {
18
19
  return testPlatform(/^iPhone/i);
19
20
  }
21
+ function isSafari() {
22
+ var ua = navigator.userAgent.toLowerCase();
23
+ return ua.includes('safari') && !ua.includes('chrome');
24
+ }
20
25
  function isMac() {
21
26
  return testPlatform(/^Mac/i);
22
27
  }
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.defaultAriaLiveMessages = void 0;
7
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
7
8
  var defaultAriaLiveMessages = exports.defaultAriaLiveMessages = {
8
9
  guidance: function guidance(props) {
9
10
  var isSearchable = props.isSearchable,
@@ -50,19 +51,22 @@ var defaultAriaLiveMessages = exports.defaultAriaLiveMessages = {
50
51
  _props$label2 = props.label,
51
52
  label = _props$label2 === void 0 ? '' : _props$label2,
52
53
  selectValue = props.selectValue,
54
+ isMulti = props.isMulti,
53
55
  isDisabled = props.isDisabled,
54
56
  isSelected = props.isSelected,
55
57
  isAppleDevice = props.isAppleDevice;
56
58
  var getArrayIndex = function getArrayIndex(arr, item) {
57
- return arr && arr.length ? "".concat(arr.indexOf(item) + 1, " of ").concat(arr.length) : '';
59
+ return arr && arr.length ? "(".concat(arr.indexOf(item) + 1, " of ").concat(arr.length, ")") : '';
58
60
  };
59
61
  if (context === 'value' && selectValue) {
60
62
  return "value ".concat(label, " focused, ").concat(getArrayIndex(selectValue, focused), ".");
61
63
  }
62
64
  if (context === 'menu' && isAppleDevice) {
63
65
  var disabled = isDisabled ? ' disabled' : '';
64
- var status = "".concat(isSelected ? ' selected' : '').concat(disabled);
65
- return "".concat(label).concat(status, ", ").concat(getArrayIndex(options, focused), ".");
66
+ // don't announce not selected for single selection
67
+ var notSelectedStatus = !isMulti && (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? '' : ' not selected';
68
+ var status = "".concat(isSelected ? ' selected' : notSelectedStatus).concat(disabled);
69
+ return "".concat(label).concat(status, ", ").concat(getArrayIndex(options, focused), ", completion selected");
66
70
  }
67
71
  return '';
68
72
  },
@@ -8,6 +8,7 @@ exports.default = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _react = require("react");
10
10
  var _react2 = require("@emotion/react");
11
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
11
12
  var _accessibility = require("../accessibility");
12
13
  var _a11yText = _interopRequireDefault(require("./internal/a11y-text"));
13
14
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -45,6 +46,9 @@ var LiveRegion = function LiveRegion(props) {
45
46
  var ariaLabel = selectProps['aria-label'] || label;
46
47
  var ariaLive = selectProps['aria-live'];
47
48
 
49
+ // for safari, we will use minimum support from aria-live region
50
+ var isA11yImprovementEnabled = (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') && !isAppleDevice;
51
+
48
52
  // Update aria live message configuration when prop changes
49
53
  var messages = (0, _react.useMemo)(function () {
50
54
  return _objectSpread(_objectSpread({}, _accessibility.defaultAriaLiveMessages), ariaLiveMessages || {});
@@ -82,10 +86,17 @@ var LiveRegion = function LiveRegion(props) {
82
86
  }
83
87
  return message;
84
88
  }, [ariaSelection, messages, isOptionDisabled, selectValue, getOptionLabel]);
89
+ var prevInputValue = (0, _react.useRef)('');
85
90
  var ariaFocused = (0, _react.useMemo)(function () {
86
91
  var focusMsg = '';
87
92
  var focused = focusedOption || focusedValue;
88
93
  var isSelected = !!(focusedOption && selectValue && selectValue.includes(focusedOption));
94
+ if ((!inputValue || inputValue === prevInputValue.current) && isA11yImprovementEnabled) {
95
+ // only announce focus option when searching when ff is on,
96
+ // for safari, we will announce for all
97
+ return '';
98
+ }
99
+ prevInputValue.current = inputValue;
89
100
  if (focused && messages.onFocus) {
90
101
  var onFocusProps = {
91
102
  focused: focused,
@@ -95,27 +106,36 @@ var LiveRegion = function LiveRegion(props) {
95
106
  options: focusableOptions,
96
107
  context: focused === focusedOption ? 'menu' : 'value',
97
108
  selectValue: selectValue,
98
- isAppleDevice: isAppleDevice
109
+ isAppleDevice: isAppleDevice,
110
+ isMulti: isMulti
99
111
  };
100
112
  focusMsg = messages.onFocus(onFocusProps);
101
113
  }
102
114
  return focusMsg;
103
- }, [focusedOption, focusedValue, getOptionLabel, isOptionDisabled, messages, focusableOptions, selectValue, isAppleDevice]);
115
+ }, [inputValue, focusedOption, focusedValue, getOptionLabel, isOptionDisabled, messages, focusableOptions, selectValue, isAppleDevice, isA11yImprovementEnabled, isMulti]);
104
116
  var ariaResults = (0, _react.useMemo)(function () {
105
117
  var resultsMsg = '';
106
118
  if (menuIsOpen && options.length && !isLoading && messages.onFilter) {
107
- var resultsMessage = screenReaderStatus({
108
- count: focusableOptions.length
109
- });
110
- resultsMsg = messages.onFilter({
111
- inputValue: inputValue,
112
- resultsMessage: resultsMessage
113
- });
119
+ var shouldAnnounceAvailableResults = !focusableOptions.length;
120
+ if (shouldAnnounceAvailableResults && (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') || !(0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement')) {
121
+ // only announce no option results when ff is on
122
+ var resultsMessage = screenReaderStatus({
123
+ count: focusableOptions.length
124
+ });
125
+ resultsMsg = messages.onFilter({
126
+ inputValue: inputValue,
127
+ resultsMessage: resultsMessage
128
+ });
129
+ }
114
130
  }
115
131
  return resultsMsg;
116
132
  }, [focusableOptions, inputValue, menuIsOpen, messages, options, screenReaderStatus, isLoading]);
117
133
  var isInitialFocus = (ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action) === 'initial-input-focus';
118
134
  var ariaGuidance = (0, _react.useMemo)(function () {
135
+ if ((0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement')) {
136
+ // don't announce guidance at all when ff is on
137
+ return '';
138
+ }
119
139
  var guidanceMsg = '';
120
140
  if (messages.guidance) {
121
141
  var context = focusedValue ? 'value' : menuIsOpen ? 'menu' : 'input';
@@ -137,16 +157,14 @@ var LiveRegion = function LiveRegion(props) {
137
157
  id: "aria-focused"
138
158
  }, ariaFocused), (0, _react2.jsx)("span", {
139
159
  id: "aria-results"
140
- }, ariaResults), (0, _react2.jsx)("span", {
160
+ }, ariaResults), !(0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') && (0, _react2.jsx)("span", {
141
161
  id: "aria-guidance"
142
162
  }, ariaGuidance));
143
163
  return (0, _react2.jsx)(_react.Fragment, null, (0, _react2.jsx)(_a11yText.default, {
144
164
  id: id
145
165
  }, isInitialFocus && ScreenReaderText), (0, _react2.jsx)(_a11yText.default, {
146
- "aria-live": ariaLive,
147
- "aria-atomic": "false",
148
- "aria-relevant": "additions text",
149
- role: "log"
166
+ "aria-live": isA11yImprovementEnabled ? 'polite' : ariaLive,
167
+ role: isA11yImprovementEnabled ? 'status' : 'log'
150
168
  }, isFocused && !isInitialFocus && ScreenReaderText));
151
169
  };
152
170
 
@@ -311,7 +311,9 @@ var MenuList = exports.MenuList = function MenuList(props) {
311
311
  'menu-list--is-multi': isMulti
312
312
  }), {
313
313
  ref: innerRef
314
- }, innerProps), children);
314
+ }, innerProps, {
315
+ tabIndex: -1
316
+ }), children);
315
317
  };
316
318
 
317
319
  // ==============================
@@ -54,7 +54,9 @@ var Option = function Option(props) {
54
54
  }), {
55
55
  ref: innerRef,
56
56
  "aria-disabled": isDisabled
57
- }, innerProps), children);
57
+ }, innerProps, {
58
+ tabIndex: -1
59
+ }), children);
58
60
  };
59
61
 
60
62
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
@@ -16,6 +16,7 @@ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/ge
16
16
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
17
17
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
18
18
  var _react = _interopRequireWildcard(require("react"));
19
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
19
20
  var _helpers = require("./accessibility/helpers");
20
21
  var _builtins = require("./builtins");
21
22
  var _components = require("./components");
@@ -258,7 +259,7 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
258
259
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "initialTouchY", 0);
259
260
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "openAfterFocus", false);
260
261
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "scrollToFocusedOptionOnUpdate", false);
261
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isAppleDevice", (0, _helpers.isAppleDevice)());
262
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isAppleDevice", (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? (0, _helpers.isSafari)() : (0, _helpers.isAppleDevice)());
262
263
  // Refs
263
264
  // ------------------------------
264
265
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "controlRef", null);
@@ -1237,7 +1238,8 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1237
1238
  labelId = _this$props8.labelId,
1238
1239
  menuIsOpen = _this$props8.menuIsOpen,
1239
1240
  required = _this$props8.required,
1240
- tabIndex = _this$props8.tabIndex;
1241
+ _this$props8$tabIndex = _this$props8.tabIndex,
1242
+ tabIndex = _this$props8$tabIndex === void 0 ? 0 : _this$props8$tabIndex;
1241
1243
  var _this$getComponents = this.getComponents(),
1242
1244
  Input = _this$getComponents.Input;
1243
1245
  var _this$state4 = this.state,
@@ -1249,7 +1251,7 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1249
1251
 
1250
1252
  // aria attributes makes the JSX "noisy", separated for clarity
1251
1253
  var ariaAttributes = _objectSpread(_objectSpread(_objectSpread({
1252
- 'aria-autocomplete': 'list',
1254
+ 'aria-autocomplete': 'both',
1253
1255
  'aria-errormessage': this.props['aria-errormessage'],
1254
1256
  'aria-expanded': menuIsOpen,
1255
1257
  'aria-haspopup': 'listbox',
@@ -1259,7 +1261,7 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1259
1261
  'aria-labelledby': this.props['aria-labelledby'] || labelId,
1260
1262
  'aria-required': required || isRequired,
1261
1263
  role: 'combobox',
1262
- 'aria-activedescendant': this.isAppleDevice ? undefined : this.state.focusedOptionId ? this.state.focusedOptionId : undefined
1264
+ 'aria-activedescendant': this.state.focusedOptionId || undefined
1263
1265
  }, menuIsOpen && {
1264
1266
  'aria-controls': this.getElementId('listbox')
1265
1267
  }), !isSearchable && {
@@ -1491,13 +1493,15 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1491
1493
  menuShouldScrollIntoView = _this$props12.menuShouldScrollIntoView,
1492
1494
  noOptionsMessage = _this$props12.noOptionsMessage,
1493
1495
  onMenuScrollToTop = _this$props12.onMenuScrollToTop,
1494
- onMenuScrollToBottom = _this$props12.onMenuScrollToBottom;
1496
+ onMenuScrollToBottom = _this$props12.onMenuScrollToBottom,
1497
+ labelId = _this$props12.labelId,
1498
+ label = _this$props12.label;
1495
1499
  if (!menuIsOpen) {
1496
1500
  return null;
1497
1501
  }
1498
1502
 
1499
1503
  // TODO: Internal Option Type here
1500
- var render = function render(props, id) {
1504
+ var render = function render(props, id, headingId) {
1501
1505
  var type = props.type,
1502
1506
  data = props.data,
1503
1507
  isDisabled = props.isDisabled,
@@ -1518,7 +1522,8 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1518
1522
  onMouseMove: onHover,
1519
1523
  onMouseOver: onHover,
1520
1524
  role: 'option',
1521
- 'aria-selected': _this4.isAppleDevice ? undefined : isSelected // is not supported on Apple devices
1525
+ 'aria-selected': !commonProps.isMulti && (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? isSelected || undefined : isSelected,
1526
+ 'aria-describedby': (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? headingId : undefined
1522
1527
  };
1523
1528
  return /*#__PURE__*/_react.default.createElement(Option, (0, _extends2.default)({}, commonProps, {
1524
1529
  innerProps: innerProps,
@@ -1535,7 +1540,8 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1535
1540
  };
1536
1541
  var menuUI;
1537
1542
  if (this.hasOptions()) {
1538
- menuUI = this.getCategorizedOptions().map(function (item) {
1543
+ var items = this.getCategorizedOptions();
1544
+ menuUI = items.map(function (item) {
1539
1545
  if (item.type === 'group') {
1540
1546
  var data = item.data,
1541
1547
  options = item.options,
@@ -1553,7 +1559,7 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1553
1559
  },
1554
1560
  label: _this4.formatGroupLabel(item.data)
1555
1561
  }), item.options.map(function (option) {
1556
- return render(option, "".concat(groupIndex, "-").concat(option.index));
1562
+ return render(option, "".concat(groupIndex, "-").concat(option.index), headingId);
1557
1563
  }));
1558
1564
  } else if (item.type === 'option') {
1559
1565
  return render(item, "".concat(item.index));
@@ -1608,11 +1614,15 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1608
1614
  _this4.getMenuListRef(instance);
1609
1615
  scrollTargetRef(instance);
1610
1616
  },
1611
- innerProps: {
1617
+ innerProps: _objectSpread({
1612
1618
  role: 'listbox',
1613
- 'aria-multiselectable': commonProps.isMulti,
1619
+ // don't add aria-multiselectable when ff is on and the value is false
1620
+ 'aria-multiselectable': (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? commonProps.isMulti || undefined : commonProps.isMulti,
1614
1621
  id: _this4.getElementId('listbox')
1615
- },
1622
+ }, (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') && {
1623
+ 'aria-label': label,
1624
+ 'aria-labelledby': labelId
1625
+ }),
1616
1626
  isLoading: isLoading,
1617
1627
  maxHeight: maxHeight,
1618
1628
  focusedOption: focusedOption
@@ -7,6 +7,10 @@ function testPlatform(re) {
7
7
  export function isIPhone() {
8
8
  return testPlatform(/^iPhone/i);
9
9
  }
10
+ export function isSafari() {
11
+ const ua = navigator.userAgent.toLowerCase();
12
+ return ua.includes('safari') && !ua.includes('chrome');
13
+ }
10
14
  export function isMac() {
11
15
  return testPlatform(/^Mac/i);
12
16
  }
@@ -1,3 +1,4 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
1
2
  export const defaultAriaLiveMessages = {
2
3
  guidance: props => {
3
4
  const {
@@ -47,18 +48,21 @@ export const defaultAriaLiveMessages = {
47
48
  options,
48
49
  label = '',
49
50
  selectValue,
51
+ isMulti,
50
52
  isDisabled,
51
53
  isSelected,
52
54
  isAppleDevice
53
55
  } = props;
54
- const getArrayIndex = (arr, item) => arr && arr.length ? `${arr.indexOf(item) + 1} of ${arr.length}` : '';
56
+ const getArrayIndex = (arr, item) => arr && arr.length ? `(${arr.indexOf(item) + 1} of ${arr.length})` : '';
55
57
  if (context === 'value' && selectValue) {
56
58
  return `value ${label} focused, ${getArrayIndex(selectValue, focused)}.`;
57
59
  }
58
60
  if (context === 'menu' && isAppleDevice) {
59
61
  const disabled = isDisabled ? ' disabled' : '';
60
- const status = `${isSelected ? ' selected' : ''}${disabled}`;
61
- return `${label}${status}, ${getArrayIndex(options, focused)}.`;
62
+ // don't announce not selected for single selection
63
+ const notSelectedStatus = !isMulti && fg('design_system_select-a11y-improvement') ? '' : ' not selected';
64
+ const status = `${isSelected ? ' selected' : notSelectedStatus}${disabled}`;
65
+ return `${label}${status}, ${getArrayIndex(options, focused)}, completion selected`;
62
66
  }
63
67
  return '';
64
68
  },
@@ -2,8 +2,9 @@
2
2
  * @jsxRuntime classic
3
3
  * @jsx jsx
4
4
  */
5
- import { Fragment, useMemo } from 'react';
5
+ import { Fragment, useMemo, useRef } from 'react';
6
6
  import { jsx } from '@emotion/react';
7
+ import { fg } from '@atlaskit/platform-feature-flags';
7
8
  import { defaultAriaLiveMessages } from '../accessibility';
8
9
  import A11yText from './internal/a11y-text';
9
10
 
@@ -41,6 +42,9 @@ const LiveRegion = props => {
41
42
  const ariaLabel = selectProps['aria-label'] || label;
42
43
  const ariaLive = selectProps['aria-live'];
43
44
 
45
+ // for safari, we will use minimum support from aria-live region
46
+ const isA11yImprovementEnabled = fg('design_system_select-a11y-improvement') && !isAppleDevice;
47
+
44
48
  // Update aria live message configuration when prop changes
45
49
  const messages = useMemo(() => ({
46
50
  ...defaultAriaLiveMessages,
@@ -80,10 +84,17 @@ const LiveRegion = props => {
80
84
  }
81
85
  return message;
82
86
  }, [ariaSelection, messages, isOptionDisabled, selectValue, getOptionLabel]);
87
+ const prevInputValue = useRef('');
83
88
  const ariaFocused = useMemo(() => {
84
89
  let focusMsg = '';
85
90
  const focused = focusedOption || focusedValue;
86
91
  const isSelected = !!(focusedOption && selectValue && selectValue.includes(focusedOption));
92
+ if ((!inputValue || inputValue === prevInputValue.current) && isA11yImprovementEnabled) {
93
+ // only announce focus option when searching when ff is on,
94
+ // for safari, we will announce for all
95
+ return '';
96
+ }
97
+ prevInputValue.current = inputValue;
87
98
  if (focused && messages.onFocus) {
88
99
  const onFocusProps = {
89
100
  focused,
@@ -93,27 +104,36 @@ const LiveRegion = props => {
93
104
  options: focusableOptions,
94
105
  context: focused === focusedOption ? 'menu' : 'value',
95
106
  selectValue,
96
- isAppleDevice
107
+ isAppleDevice,
108
+ isMulti
97
109
  };
98
110
  focusMsg = messages.onFocus(onFocusProps);
99
111
  }
100
112
  return focusMsg;
101
- }, [focusedOption, focusedValue, getOptionLabel, isOptionDisabled, messages, focusableOptions, selectValue, isAppleDevice]);
113
+ }, [inputValue, focusedOption, focusedValue, getOptionLabel, isOptionDisabled, messages, focusableOptions, selectValue, isAppleDevice, isA11yImprovementEnabled, isMulti]);
102
114
  const ariaResults = useMemo(() => {
103
115
  let resultsMsg = '';
104
116
  if (menuIsOpen && options.length && !isLoading && messages.onFilter) {
105
- const resultsMessage = screenReaderStatus({
106
- count: focusableOptions.length
107
- });
108
- resultsMsg = messages.onFilter({
109
- inputValue,
110
- resultsMessage
111
- });
117
+ const shouldAnnounceAvailableResults = !focusableOptions.length;
118
+ if (shouldAnnounceAvailableResults && fg('design_system_select-a11y-improvement') || !fg('design_system_select-a11y-improvement')) {
119
+ // only announce no option results when ff is on
120
+ const resultsMessage = screenReaderStatus({
121
+ count: focusableOptions.length
122
+ });
123
+ resultsMsg = messages.onFilter({
124
+ inputValue,
125
+ resultsMessage
126
+ });
127
+ }
112
128
  }
113
129
  return resultsMsg;
114
130
  }, [focusableOptions, inputValue, menuIsOpen, messages, options, screenReaderStatus, isLoading]);
115
131
  const isInitialFocus = (ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action) === 'initial-input-focus';
116
132
  const ariaGuidance = useMemo(() => {
133
+ if (fg('design_system_select-a11y-improvement')) {
134
+ // don't announce guidance at all when ff is on
135
+ return '';
136
+ }
117
137
  let guidanceMsg = '';
118
138
  if (messages.guidance) {
119
139
  const context = focusedValue ? 'value' : menuIsOpen ? 'menu' : 'input';
@@ -135,16 +155,14 @@ const LiveRegion = props => {
135
155
  id: "aria-focused"
136
156
  }, ariaFocused), jsx("span", {
137
157
  id: "aria-results"
138
- }, ariaResults), jsx("span", {
158
+ }, ariaResults), !fg('design_system_select-a11y-improvement') && jsx("span", {
139
159
  id: "aria-guidance"
140
160
  }, ariaGuidance));
141
161
  return jsx(Fragment, null, jsx(A11yText, {
142
162
  id: id
143
163
  }, isInitialFocus && ScreenReaderText), jsx(A11yText, {
144
- "aria-live": ariaLive,
145
- "aria-atomic": "false",
146
- "aria-relevant": "additions text",
147
- role: "log"
164
+ "aria-live": isA11yImprovementEnabled ? 'polite' : ariaLive,
165
+ role: isA11yImprovementEnabled ? 'status' : 'log'
148
166
  }, isFocused && !isInitialFocus && ScreenReaderText));
149
167
  };
150
168
 
@@ -314,7 +314,9 @@ export const MenuList = props => {
314
314
  'menu-list--is-multi': isMulti
315
315
  }), {
316
316
  ref: innerRef
317
- }, innerProps), children);
317
+ }, innerProps, {
318
+ tabIndex: -1
319
+ }), children);
318
320
  };
319
321
 
320
322
  // ==============================
@@ -49,7 +49,9 @@ const Option = props => {
49
49
  }), {
50
50
  ref: innerRef,
51
51
  "aria-disabled": isDisabled
52
- }, innerProps), children);
52
+ }, innerProps, {
53
+ tabIndex: -1
54
+ }), children);
53
55
  };
54
56
 
55
57
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
@@ -1,7 +1,8 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
  import React, { Component } from 'react';
4
- import { isAppleDevice } from './accessibility/helpers';
4
+ import { fg } from '@atlaskit/platform-feature-flags';
5
+ import { isAppleDevice, isSafari } from './accessibility/helpers';
5
6
  import { formatGroupLabel as formatGroupLabelBuiltin, getOptionLabel as getOptionLabelBuiltin, getOptionValue as getOptionValueBuiltin, isOptionDisabled as isOptionDisabledBuiltin } from './builtins';
6
7
  import { defaultComponents } from './components';
7
8
  import { DummyInput, RequiredInput, ScrollManager } from './components/internal';
@@ -225,7 +226,7 @@ export default class Select extends Component {
225
226
  _defineProperty(this, "initialTouchY", 0);
226
227
  _defineProperty(this, "openAfterFocus", false);
227
228
  _defineProperty(this, "scrollToFocusedOptionOnUpdate", false);
228
- _defineProperty(this, "isAppleDevice", isAppleDevice());
229
+ _defineProperty(this, "isAppleDevice", fg('design_system_select-a11y-improvement') ? isSafari() : isAppleDevice());
229
230
  // Refs
230
231
  // ------------------------------
231
232
  _defineProperty(this, "controlRef", null);
@@ -1241,7 +1242,7 @@ export default class Select extends Component {
1241
1242
  labelId,
1242
1243
  menuIsOpen,
1243
1244
  required,
1244
- tabIndex
1245
+ tabIndex = 0
1245
1246
  } = this.props;
1246
1247
  const {
1247
1248
  Input
@@ -1258,7 +1259,7 @@ export default class Select extends Component {
1258
1259
 
1259
1260
  // aria attributes makes the JSX "noisy", separated for clarity
1260
1261
  const ariaAttributes = {
1261
- 'aria-autocomplete': 'list',
1262
+ 'aria-autocomplete': 'both',
1262
1263
  'aria-errormessage': this.props['aria-errormessage'],
1263
1264
  'aria-expanded': menuIsOpen,
1264
1265
  'aria-haspopup': 'listbox',
@@ -1268,7 +1269,7 @@ export default class Select extends Component {
1268
1269
  'aria-labelledby': this.props['aria-labelledby'] || labelId,
1269
1270
  'aria-required': required || isRequired,
1270
1271
  role: 'combobox',
1271
- 'aria-activedescendant': this.isAppleDevice ? undefined : this.state.focusedOptionId ? this.state.focusedOptionId : undefined,
1272
+ 'aria-activedescendant': this.state.focusedOptionId || undefined,
1272
1273
  ...(menuIsOpen && {
1273
1274
  'aria-controls': this.getElementId('listbox')
1274
1275
  }),
@@ -1521,14 +1522,16 @@ export default class Select extends Component {
1521
1522
  menuShouldScrollIntoView,
1522
1523
  noOptionsMessage,
1523
1524
  onMenuScrollToTop,
1524
- onMenuScrollToBottom
1525
+ onMenuScrollToBottom,
1526
+ labelId,
1527
+ label
1525
1528
  } = this.props;
1526
1529
  if (!menuIsOpen) {
1527
1530
  return null;
1528
1531
  }
1529
1532
 
1530
1533
  // TODO: Internal Option Type here
1531
- const render = (props, id) => {
1534
+ const render = (props, id, headingId) => {
1532
1535
  const {
1533
1536
  type,
1534
1537
  data,
@@ -1547,7 +1550,8 @@ export default class Select extends Component {
1547
1550
  onMouseMove: onHover,
1548
1551
  onMouseOver: onHover,
1549
1552
  role: 'option',
1550
- 'aria-selected': this.isAppleDevice ? undefined : isSelected // is not supported on Apple devices
1553
+ 'aria-selected': !commonProps.isMulti && fg('design_system_select-a11y-improvement') ? isSelected || undefined : isSelected,
1554
+ 'aria-describedby': fg('design_system_select-a11y-improvement') ? headingId : undefined
1551
1555
  };
1552
1556
  return /*#__PURE__*/React.createElement(Option, _extends({}, commonProps, {
1553
1557
  innerProps: innerProps,
@@ -1564,7 +1568,8 @@ export default class Select extends Component {
1564
1568
  };
1565
1569
  let menuUI;
1566
1570
  if (this.hasOptions()) {
1567
- menuUI = this.getCategorizedOptions().map(item => {
1571
+ const items = this.getCategorizedOptions();
1572
+ menuUI = items.map(item => {
1568
1573
  if (item.type === 'group') {
1569
1574
  const {
1570
1575
  data,
@@ -1583,7 +1588,7 @@ export default class Select extends Component {
1583
1588
  data: item.data
1584
1589
  },
1585
1590
  label: this.formatGroupLabel(item.data)
1586
- }), item.options.map(option => render(option, `${groupIndex}-${option.index}`)));
1591
+ }), item.options.map(option => render(option, `${groupIndex}-${option.index}`, headingId)));
1587
1592
  } else if (item.type === 'option') {
1588
1593
  return render(item, `${item.index}`);
1589
1594
  }
@@ -1639,8 +1644,14 @@ export default class Select extends Component {
1639
1644
  },
1640
1645
  innerProps: {
1641
1646
  role: 'listbox',
1642
- 'aria-multiselectable': commonProps.isMulti,
1643
- id: this.getElementId('listbox')
1647
+ // don't add aria-multiselectable when ff is on and the value is false
1648
+ 'aria-multiselectable': fg('design_system_select-a11y-improvement') ? commonProps.isMulti || undefined : commonProps.isMulti,
1649
+ id: this.getElementId('listbox'),
1650
+ // add aditional label on listbox when ff is on
1651
+ ...(fg('design_system_select-a11y-improvement') && {
1652
+ 'aria-label': label,
1653
+ 'aria-labelledby': labelId
1654
+ })
1644
1655
  },
1645
1656
  isLoading: isLoading,
1646
1657
  maxHeight: maxHeight,
@@ -7,6 +7,10 @@ function testPlatform(re) {
7
7
  export function isIPhone() {
8
8
  return testPlatform(/^iPhone/i);
9
9
  }
10
+ export function isSafari() {
11
+ var ua = navigator.userAgent.toLowerCase();
12
+ return ua.includes('safari') && !ua.includes('chrome');
13
+ }
10
14
  export function isMac() {
11
15
  return testPlatform(/^Mac/i);
12
16
  }
@@ -1,3 +1,4 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
1
2
  export var defaultAriaLiveMessages = {
2
3
  guidance: function guidance(props) {
3
4
  var isSearchable = props.isSearchable,
@@ -44,19 +45,22 @@ export var defaultAriaLiveMessages = {
44
45
  _props$label2 = props.label,
45
46
  label = _props$label2 === void 0 ? '' : _props$label2,
46
47
  selectValue = props.selectValue,
48
+ isMulti = props.isMulti,
47
49
  isDisabled = props.isDisabled,
48
50
  isSelected = props.isSelected,
49
51
  isAppleDevice = props.isAppleDevice;
50
52
  var getArrayIndex = function getArrayIndex(arr, item) {
51
- return arr && arr.length ? "".concat(arr.indexOf(item) + 1, " of ").concat(arr.length) : '';
53
+ return arr && arr.length ? "(".concat(arr.indexOf(item) + 1, " of ").concat(arr.length, ")") : '';
52
54
  };
53
55
  if (context === 'value' && selectValue) {
54
56
  return "value ".concat(label, " focused, ").concat(getArrayIndex(selectValue, focused), ".");
55
57
  }
56
58
  if (context === 'menu' && isAppleDevice) {
57
59
  var disabled = isDisabled ? ' disabled' : '';
58
- var status = "".concat(isSelected ? ' selected' : '').concat(disabled);
59
- return "".concat(label).concat(status, ", ").concat(getArrayIndex(options, focused), ".");
60
+ // don't announce not selected for single selection
61
+ var notSelectedStatus = !isMulti && fg('design_system_select-a11y-improvement') ? '' : ' not selected';
62
+ var status = "".concat(isSelected ? ' selected' : notSelectedStatus).concat(disabled);
63
+ return "".concat(label).concat(status, ", ").concat(getArrayIndex(options, focused), ", completion selected");
60
64
  }
61
65
  return '';
62
66
  },
@@ -5,8 +5,9 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
5
5
  * @jsxRuntime classic
6
6
  * @jsx jsx
7
7
  */
8
- import { Fragment, useMemo } from 'react';
8
+ import { Fragment, useMemo, useRef } from 'react';
9
9
  import { jsx } from '@emotion/react';
10
+ import { fg } from '@atlaskit/platform-feature-flags';
10
11
  import { defaultAriaLiveMessages } from '../accessibility';
11
12
  import A11yText from './internal/a11y-text';
12
13
 
@@ -40,6 +41,9 @@ var LiveRegion = function LiveRegion(props) {
40
41
  var ariaLabel = selectProps['aria-label'] || label;
41
42
  var ariaLive = selectProps['aria-live'];
42
43
 
44
+ // for safari, we will use minimum support from aria-live region
45
+ var isA11yImprovementEnabled = fg('design_system_select-a11y-improvement') && !isAppleDevice;
46
+
43
47
  // Update aria live message configuration when prop changes
44
48
  var messages = useMemo(function () {
45
49
  return _objectSpread(_objectSpread({}, defaultAriaLiveMessages), ariaLiveMessages || {});
@@ -77,10 +81,17 @@ var LiveRegion = function LiveRegion(props) {
77
81
  }
78
82
  return message;
79
83
  }, [ariaSelection, messages, isOptionDisabled, selectValue, getOptionLabel]);
84
+ var prevInputValue = useRef('');
80
85
  var ariaFocused = useMemo(function () {
81
86
  var focusMsg = '';
82
87
  var focused = focusedOption || focusedValue;
83
88
  var isSelected = !!(focusedOption && selectValue && selectValue.includes(focusedOption));
89
+ if ((!inputValue || inputValue === prevInputValue.current) && isA11yImprovementEnabled) {
90
+ // only announce focus option when searching when ff is on,
91
+ // for safari, we will announce for all
92
+ return '';
93
+ }
94
+ prevInputValue.current = inputValue;
84
95
  if (focused && messages.onFocus) {
85
96
  var onFocusProps = {
86
97
  focused: focused,
@@ -90,27 +101,36 @@ var LiveRegion = function LiveRegion(props) {
90
101
  options: focusableOptions,
91
102
  context: focused === focusedOption ? 'menu' : 'value',
92
103
  selectValue: selectValue,
93
- isAppleDevice: isAppleDevice
104
+ isAppleDevice: isAppleDevice,
105
+ isMulti: isMulti
94
106
  };
95
107
  focusMsg = messages.onFocus(onFocusProps);
96
108
  }
97
109
  return focusMsg;
98
- }, [focusedOption, focusedValue, getOptionLabel, isOptionDisabled, messages, focusableOptions, selectValue, isAppleDevice]);
110
+ }, [inputValue, focusedOption, focusedValue, getOptionLabel, isOptionDisabled, messages, focusableOptions, selectValue, isAppleDevice, isA11yImprovementEnabled, isMulti]);
99
111
  var ariaResults = useMemo(function () {
100
112
  var resultsMsg = '';
101
113
  if (menuIsOpen && options.length && !isLoading && messages.onFilter) {
102
- var resultsMessage = screenReaderStatus({
103
- count: focusableOptions.length
104
- });
105
- resultsMsg = messages.onFilter({
106
- inputValue: inputValue,
107
- resultsMessage: resultsMessage
108
- });
114
+ var shouldAnnounceAvailableResults = !focusableOptions.length;
115
+ if (shouldAnnounceAvailableResults && fg('design_system_select-a11y-improvement') || !fg('design_system_select-a11y-improvement')) {
116
+ // only announce no option results when ff is on
117
+ var resultsMessage = screenReaderStatus({
118
+ count: focusableOptions.length
119
+ });
120
+ resultsMsg = messages.onFilter({
121
+ inputValue: inputValue,
122
+ resultsMessage: resultsMessage
123
+ });
124
+ }
109
125
  }
110
126
  return resultsMsg;
111
127
  }, [focusableOptions, inputValue, menuIsOpen, messages, options, screenReaderStatus, isLoading]);
112
128
  var isInitialFocus = (ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action) === 'initial-input-focus';
113
129
  var ariaGuidance = useMemo(function () {
130
+ if (fg('design_system_select-a11y-improvement')) {
131
+ // don't announce guidance at all when ff is on
132
+ return '';
133
+ }
114
134
  var guidanceMsg = '';
115
135
  if (messages.guidance) {
116
136
  var context = focusedValue ? 'value' : menuIsOpen ? 'menu' : 'input';
@@ -132,16 +152,14 @@ var LiveRegion = function LiveRegion(props) {
132
152
  id: "aria-focused"
133
153
  }, ariaFocused), jsx("span", {
134
154
  id: "aria-results"
135
- }, ariaResults), jsx("span", {
155
+ }, ariaResults), !fg('design_system_select-a11y-improvement') && jsx("span", {
136
156
  id: "aria-guidance"
137
157
  }, ariaGuidance));
138
158
  return jsx(Fragment, null, jsx(A11yText, {
139
159
  id: id
140
160
  }, isInitialFocus && ScreenReaderText), jsx(A11yText, {
141
- "aria-live": ariaLive,
142
- "aria-atomic": "false",
143
- "aria-relevant": "additions text",
144
- role: "log"
161
+ "aria-live": isA11yImprovementEnabled ? 'polite' : ariaLive,
162
+ role: isA11yImprovementEnabled ? 'status' : 'log'
145
163
  }, isFocused && !isInitialFocus && ScreenReaderText));
146
164
  };
147
165
 
@@ -307,7 +307,9 @@ export var MenuList = function MenuList(props) {
307
307
  'menu-list--is-multi': isMulti
308
308
  }), {
309
309
  ref: innerRef
310
- }, innerProps), children);
310
+ }, innerProps, {
311
+ tabIndex: -1
312
+ }), children);
311
313
  };
312
314
 
313
315
  // ==============================
@@ -49,7 +49,9 @@ var Option = function Option(props) {
49
49
  }), {
50
50
  ref: innerRef,
51
51
  "aria-disabled": isDisabled
52
- }, innerProps), children);
52
+ }, innerProps, {
53
+ tabIndex: -1
54
+ }), children);
53
55
  };
54
56
 
55
57
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
@@ -12,7 +12,8 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
12
12
  function _createSuper(t) { var r = _isNativeReflectConstruct(); return function () { var e, o = _getPrototypeOf(t); if (r) { var s = _getPrototypeOf(this).constructor; e = Reflect.construct(o, arguments, s); } else e = o.apply(this, arguments); return _possibleConstructorReturn(this, e); }; }
13
13
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
14
14
  import React, { Component } from 'react';
15
- import { isAppleDevice } from './accessibility/helpers';
15
+ import { fg } from '@atlaskit/platform-feature-flags';
16
+ import { isAppleDevice, isSafari } from './accessibility/helpers';
16
17
  import { formatGroupLabel as formatGroupLabelBuiltin, getOptionLabel as getOptionLabelBuiltin, getOptionValue as getOptionValueBuiltin, isOptionDisabled as isOptionDisabledBuiltin } from './builtins';
17
18
  import { defaultComponents } from './components';
18
19
  import { DummyInput, RequiredInput, ScrollManager } from './components/internal';
@@ -248,7 +249,7 @@ var Select = /*#__PURE__*/function (_Component) {
248
249
  _defineProperty(_assertThisInitialized(_this), "initialTouchY", 0);
249
250
  _defineProperty(_assertThisInitialized(_this), "openAfterFocus", false);
250
251
  _defineProperty(_assertThisInitialized(_this), "scrollToFocusedOptionOnUpdate", false);
251
- _defineProperty(_assertThisInitialized(_this), "isAppleDevice", isAppleDevice());
252
+ _defineProperty(_assertThisInitialized(_this), "isAppleDevice", fg('design_system_select-a11y-improvement') ? isSafari() : isAppleDevice());
252
253
  // Refs
253
254
  // ------------------------------
254
255
  _defineProperty(_assertThisInitialized(_this), "controlRef", null);
@@ -1227,7 +1228,8 @@ var Select = /*#__PURE__*/function (_Component) {
1227
1228
  labelId = _this$props8.labelId,
1228
1229
  menuIsOpen = _this$props8.menuIsOpen,
1229
1230
  required = _this$props8.required,
1230
- tabIndex = _this$props8.tabIndex;
1231
+ _this$props8$tabIndex = _this$props8.tabIndex,
1232
+ tabIndex = _this$props8$tabIndex === void 0 ? 0 : _this$props8$tabIndex;
1231
1233
  var _this$getComponents = this.getComponents(),
1232
1234
  Input = _this$getComponents.Input;
1233
1235
  var _this$state4 = this.state,
@@ -1239,7 +1241,7 @@ var Select = /*#__PURE__*/function (_Component) {
1239
1241
 
1240
1242
  // aria attributes makes the JSX "noisy", separated for clarity
1241
1243
  var ariaAttributes = _objectSpread(_objectSpread(_objectSpread({
1242
- 'aria-autocomplete': 'list',
1244
+ 'aria-autocomplete': 'both',
1243
1245
  'aria-errormessage': this.props['aria-errormessage'],
1244
1246
  'aria-expanded': menuIsOpen,
1245
1247
  'aria-haspopup': 'listbox',
@@ -1249,7 +1251,7 @@ var Select = /*#__PURE__*/function (_Component) {
1249
1251
  'aria-labelledby': this.props['aria-labelledby'] || labelId,
1250
1252
  'aria-required': required || isRequired,
1251
1253
  role: 'combobox',
1252
- 'aria-activedescendant': this.isAppleDevice ? undefined : this.state.focusedOptionId ? this.state.focusedOptionId : undefined
1254
+ 'aria-activedescendant': this.state.focusedOptionId || undefined
1253
1255
  }, menuIsOpen && {
1254
1256
  'aria-controls': this.getElementId('listbox')
1255
1257
  }), !isSearchable && {
@@ -1481,13 +1483,15 @@ var Select = /*#__PURE__*/function (_Component) {
1481
1483
  menuShouldScrollIntoView = _this$props12.menuShouldScrollIntoView,
1482
1484
  noOptionsMessage = _this$props12.noOptionsMessage,
1483
1485
  onMenuScrollToTop = _this$props12.onMenuScrollToTop,
1484
- onMenuScrollToBottom = _this$props12.onMenuScrollToBottom;
1486
+ onMenuScrollToBottom = _this$props12.onMenuScrollToBottom,
1487
+ labelId = _this$props12.labelId,
1488
+ label = _this$props12.label;
1485
1489
  if (!menuIsOpen) {
1486
1490
  return null;
1487
1491
  }
1488
1492
 
1489
1493
  // TODO: Internal Option Type here
1490
- var render = function render(props, id) {
1494
+ var render = function render(props, id, headingId) {
1491
1495
  var type = props.type,
1492
1496
  data = props.data,
1493
1497
  isDisabled = props.isDisabled,
@@ -1508,7 +1512,8 @@ var Select = /*#__PURE__*/function (_Component) {
1508
1512
  onMouseMove: onHover,
1509
1513
  onMouseOver: onHover,
1510
1514
  role: 'option',
1511
- 'aria-selected': _this4.isAppleDevice ? undefined : isSelected // is not supported on Apple devices
1515
+ 'aria-selected': !commonProps.isMulti && fg('design_system_select-a11y-improvement') ? isSelected || undefined : isSelected,
1516
+ 'aria-describedby': fg('design_system_select-a11y-improvement') ? headingId : undefined
1512
1517
  };
1513
1518
  return /*#__PURE__*/React.createElement(Option, _extends({}, commonProps, {
1514
1519
  innerProps: innerProps,
@@ -1525,7 +1530,8 @@ var Select = /*#__PURE__*/function (_Component) {
1525
1530
  };
1526
1531
  var menuUI;
1527
1532
  if (this.hasOptions()) {
1528
- menuUI = this.getCategorizedOptions().map(function (item) {
1533
+ var items = this.getCategorizedOptions();
1534
+ menuUI = items.map(function (item) {
1529
1535
  if (item.type === 'group') {
1530
1536
  var data = item.data,
1531
1537
  options = item.options,
@@ -1543,7 +1549,7 @@ var Select = /*#__PURE__*/function (_Component) {
1543
1549
  },
1544
1550
  label: _this4.formatGroupLabel(item.data)
1545
1551
  }), item.options.map(function (option) {
1546
- return render(option, "".concat(groupIndex, "-").concat(option.index));
1552
+ return render(option, "".concat(groupIndex, "-").concat(option.index), headingId);
1547
1553
  }));
1548
1554
  } else if (item.type === 'option') {
1549
1555
  return render(item, "".concat(item.index));
@@ -1598,11 +1604,15 @@ var Select = /*#__PURE__*/function (_Component) {
1598
1604
  _this4.getMenuListRef(instance);
1599
1605
  scrollTargetRef(instance);
1600
1606
  },
1601
- innerProps: {
1607
+ innerProps: _objectSpread({
1602
1608
  role: 'listbox',
1603
- 'aria-multiselectable': commonProps.isMulti,
1609
+ // don't add aria-multiselectable when ff is on and the value is false
1610
+ 'aria-multiselectable': fg('design_system_select-a11y-improvement') ? commonProps.isMulti || undefined : commonProps.isMulti,
1604
1611
  id: _this4.getElementId('listbox')
1605
- },
1612
+ }, fg('design_system_select-a11y-improvement') && {
1613
+ 'aria-label': label,
1614
+ 'aria-labelledby': labelId
1615
+ }),
1606
1616
  isLoading: isLoading,
1607
1617
  maxHeight: maxHeight,
1608
1618
  focusedOption: focusedOption
@@ -1,4 +1,5 @@
1
1
  export declare function isIPhone(): boolean;
2
+ export declare function isSafari(): boolean;
2
3
  export declare function isMac(): boolean;
3
4
  export declare function isIPad(): boolean;
4
5
  export declare function isIOS(): boolean;
@@ -94,6 +94,10 @@ export interface AriaOnFocusProps<Option, Group extends GroupBase<Option>> {
94
94
  * Boolean indicating whether user uses Apple device
95
95
  */
96
96
  isAppleDevice: boolean;
97
+ /**
98
+ * Boolean value of selectProp isMulti
99
+ */
100
+ isMulti: boolean;
97
101
  }
98
102
  export type AriaGuidance = (props: AriaGuidanceProps) => string;
99
103
  export type AriaOnChange<Option, IsMulti extends boolean> = (props: AriaOnChangeProps<Option, IsMulti>) => string;
@@ -1,4 +1,5 @@
1
1
  export declare function isIPhone(): boolean;
2
+ export declare function isSafari(): boolean;
2
3
  export declare function isMac(): boolean;
3
4
  export declare function isIPad(): boolean;
4
5
  export declare function isIOS(): boolean;
@@ -94,6 +94,10 @@ export interface AriaOnFocusProps<Option, Group extends GroupBase<Option>> {
94
94
  * Boolean indicating whether user uses Apple device
95
95
  */
96
96
  isAppleDevice: boolean;
97
+ /**
98
+ * Boolean value of selectProp isMulti
99
+ */
100
+ isMulti: boolean;
97
101
  }
98
102
  export type AriaGuidance = (props: AriaGuidanceProps) => string;
99
103
  export type AriaOnChange<Option, IsMulti extends boolean> = (props: AriaOnChangeProps<Option, IsMulti>) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-select",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "A forked version of react-select to only be used in atlaskit/select",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -27,6 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@atlaskit/ds-lib": "^3.1.0",
30
+ "@atlaskit/platform-feature-flags": "^0.3.0",
30
31
  "@babel/runtime": "^7.0.0",
31
32
  "@emotion/react": "^11.7.1",
32
33
  "@floating-ui/dom": "^1.0.1",
@@ -49,6 +50,11 @@
49
50
  "typescript": "~5.4.2",
50
51
  "wait-for-expect": "^1.2.0"
51
52
  },
53
+ "platform-feature-flags": {
54
+ "design_system_select-a11y-improvement": {
55
+ "type": "boolean"
56
+ }
57
+ },
52
58
  "techstack": {
53
59
  "@atlassian/frontend": {
54
60
  "import-structure": [