@atlaskit/react-select 2.6.6 → 2.7.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.
@@ -1,5 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _readOnlyError from "@babel/runtime/helpers/readOnlyError";
3
+ import _typeof from "@babel/runtime/helpers/typeof";
3
4
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
4
5
  import _createClass from "@babel/runtime/helpers/createClass";
5
6
  import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
@@ -11,9 +12,8 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
11
12
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
13
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
13
14
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
14
- /* eslint-disable @atlaskit/platform/ensure-feature-flag-prefix */
15
15
  import React, { Component } from 'react';
16
- import { isAppleDevice } from '@atlaskit/ds-lib/device-check';
16
+ import { isAppleDevice, isSafari } from '@atlaskit/ds-lib/device-check';
17
17
  import { fg } from '@atlaskit/platform-feature-flags';
18
18
  import { formatGroupLabel as formatGroupLabelBuiltin, getOptionLabel as getOptionLabelBuiltin, getOptionValue as getOptionValueBuiltin, isOptionDisabled as isOptionDisabledBuiltin } from './builtins';
19
19
  import { defaultComponents } from './components';
@@ -25,9 +25,6 @@ import { createFilter } from './filters';
25
25
  import { defaultStyles } from './styles';
26
26
  import { classNames, cleanValue, filterUnsupportedSelectors, isDocumentElement, isMobileDevice, isTouchCapable, multiValueAsValue, noop, notNullish, scrollIntoView, singleValueAsValue, valueTernary } from './utils';
27
27
  export var defaultProps = {
28
- // aria-live is by default with the live region so we don't need it
29
- // eslint-disable-next-line @atlaskit/platform/no-module-level-eval
30
- 'aria-live': fg('design_system_select-a11y-improvement') ? undefined : 'polite',
31
28
  backspaceRemovesValue: true,
32
29
  blurInputOnSelect: isTouchCapable(),
33
30
  captureMenuScroll: !isTouchCapable(),
@@ -251,7 +248,6 @@ var Select = /*#__PURE__*/function (_Component) {
251
248
  _defineProperty(_this, "initialTouchY", 0);
252
249
  _defineProperty(_this, "openAfterFocus", false);
253
250
  _defineProperty(_this, "scrollToFocusedOptionOnUpdate", false);
254
- _defineProperty(_this, "isVoiceOver", fg('design_system_select-a11y-improvement') && isAppleDevice());
255
251
  // Refs
256
252
  // ------------------------------
257
253
  _defineProperty(_this, "controlRef", null);
@@ -957,17 +953,70 @@ var Select = /*#__PURE__*/function (_Component) {
957
953
  openAtIndex = selectedIndex;
958
954
  }
959
955
  }
956
+ var focusedOption = focusableOptions[openAtIndex];
960
957
 
961
958
  // only scroll if the menu isn't already open
962
959
  this.scrollToFocusedOptionOnUpdate = !(isFocused && this.menuListRef);
963
960
  this.setState({
964
961
  inputIsHiddenAfterUpdate: false,
965
962
  focusedValue: null,
966
- focusedOption: focusableOptions[openAtIndex],
967
- focusedOptionId: this.getFocusedOptionId(focusableOptions[openAtIndex])
963
+ focusedOption: focusedOption,
964
+ focusedOptionId: this.getFocusedOptionId(focusedOption)
968
965
  }, function () {
969
966
  return _this2.onMenuOpen();
970
967
  });
968
+ isSafari() && focusedOption && this.updateInputLabel(this.calculateInputLabel(focusedOption, openAtIndex));
969
+ }
970
+ }, {
971
+ key: "updateInputLabel",
972
+ value: function updateInputLabel(inputLabel) {
973
+ var _this3 = this;
974
+ if (inputLabel) {
975
+ var _this$inputRef;
976
+ (_this$inputRef = this.inputRef) === null || _this$inputRef === void 0 || _this$inputRef.setAttribute('aria-label', inputLabel);
977
+ setTimeout(function () {
978
+ var normalizedLabel = _this3.props['aria-label'] || _this3.props.label;
979
+ if (normalizedLabel) {
980
+ var _this3$inputRef;
981
+ (_this3$inputRef = _this3.inputRef) === null || _this3$inputRef === void 0 || _this3$inputRef.setAttribute('aria-label', normalizedLabel);
982
+ } else {
983
+ var _this3$inputRef2;
984
+ (_this3$inputRef2 = _this3.inputRef) === null || _this3$inputRef2 === void 0 || _this3$inputRef2.removeAttribute('aria-label');
985
+ }
986
+ }, 500);
987
+ }
988
+ }
989
+ }, {
990
+ key: "calculateInputLabel",
991
+ value: function calculateInputLabel(focusedOption, optionIndex) {
992
+ var _this4 = this;
993
+ var options = this.props.options;
994
+ var isOptionsGrouped = options === null || options === void 0 ? void 0 : options.every(function (obj) {
995
+ return _typeof(obj) === 'object' && obj !== null && 'options' in obj;
996
+ });
997
+ var inputLabel = this.getOptionLabel(focusedOption);
998
+ var isOptionFocused = function isOptionFocused(option) {
999
+ return _this4.getOptionLabel(option) === inputLabel;
1000
+ };
1001
+ var groupData = options === null || options === void 0 ? void 0 : options.find(function (option) {
1002
+ var _groupCandidate$optio, _groupCandidate$optio2;
1003
+ var groupCandidate = option;
1004
+ return (_groupCandidate$optio = (_groupCandidate$optio2 = groupCandidate.options) === null || _groupCandidate$optio2 === void 0 ? void 0 : _groupCandidate$optio2.some(isOptionFocused)) !== null && _groupCandidate$optio !== void 0 ? _groupCandidate$optio : false;
1005
+ });
1006
+ if (isOptionsGrouped) {
1007
+ var _groupData$options$fi;
1008
+ var groupOptionIndex = (_groupData$options$fi = groupData === null || groupData === void 0 ? void 0 : groupData.options.findIndex(isOptionFocused)) !== null && _groupData$options$fi !== void 0 ? _groupData$options$fi : 0;
1009
+ var totalLength = options === null || options === void 0 ? void 0 : options.reduce(function (acc, currentGroup) {
1010
+ var _group$options;
1011
+ var group = currentGroup;
1012
+ acc += group === null || group === void 0 || (_group$options = group.options) === null || _group$options === void 0 ? void 0 : _group$options.length;
1013
+ return acc;
1014
+ }, 0);
1015
+ inputLabel = "".concat(inputLabel, ", ").concat(groupData === null || groupData === void 0 ? void 0 : groupData.label, " (").concat(groupOptionIndex + 1, " of ").concat(totalLength, ")");
1016
+ } else {
1017
+ inputLabel = "".concat(inputLabel, " (").concat(optionIndex + 1, " of ").concat(options === null || options === void 0 ? void 0 : options.length, ")");
1018
+ }
1019
+ return inputLabel;
971
1020
  }
972
1021
  }, {
973
1022
  key: "focusValue",
@@ -1150,24 +1199,36 @@ var Select = /*#__PURE__*/function (_Component) {
1150
1199
  }
1151
1200
  }, {
1152
1201
  key: "calculateDescription",
1153
- value: function calculateDescription(action) {
1154
- var descriptionProp = this.props['aria-describedby'] || this.props['descriptionId'];
1202
+ value: function calculateDescription() {
1203
+ var descriptionProp = this.props['aria-describedby'] || this.props.descriptionId;
1155
1204
  var isMulti = this.props.isMulti;
1156
- var selectValue = this.state.selectValue;
1157
- var defaultDescription = selectValue.length ? this.getElementId('live-region') : this.getElementId('placeholder');
1158
- if (!isMulti && selectValue.length && action !== 'initial-input-focus') {
1159
- return;
1205
+ var hasValue = this.state.selectValue.length > 0;
1206
+
1207
+ // Determine base description based on selection state
1208
+ var baseDescriptionId = hasValue ? isMulti ? '' : this.getElementId('single-value') : this.getElementId('placeholder');
1209
+
1210
+ // Fast path for single select with no description prop
1211
+ if (!isMulti && !descriptionProp) {
1212
+ return {
1213
+ 'aria-describedby': baseDescriptionId
1214
+ };
1160
1215
  }
1216
+
1217
+ // Build the describedby string efficiently
1218
+ var describedBy = baseDescriptionId;
1219
+ // Add description prop if it exists
1220
+ if (descriptionProp) {
1221
+ describedBy = describedBy ? "".concat(descriptionProp, " ").concat(describedBy) : descriptionProp;
1222
+ }
1223
+
1224
+ // For multi-select, always add multi-message ID
1161
1225
  if (isMulti) {
1162
1226
  var multiMessage = this.getElementId('multi-message');
1163
- return {
1164
- 'aria-describedby': descriptionProp ? [descriptionProp, defaultDescription, multiMessage].join(' ') : [defaultDescription, multiMessage].join(' ')
1165
- };
1166
- } else {
1167
- return {
1168
- 'aria-describedby': descriptionProp ? [descriptionProp, defaultDescription].join(' ') : defaultDescription
1169
- };
1227
+ describedBy = describedBy ? "".concat(describedBy, " ").concat(multiMessage) : multiMessage;
1170
1228
  }
1229
+ return {
1230
+ 'aria-describedby': describedBy
1231
+ };
1171
1232
  }
1172
1233
  }, {
1173
1234
  key: "startListeningComposition",
@@ -1231,7 +1292,6 @@ var Select = /*#__PURE__*/function (_Component) {
1231
1292
  // ==============================
1232
1293
  function renderInput() {
1233
1294
  var _this$props8 = this.props,
1234
- descriptionId = _this$props8.descriptionId,
1235
1295
  form = _this$props8.form,
1236
1296
  inputId = _this$props8.inputId,
1237
1297
  inputValue = _this$props8.inputValue,
@@ -1248,9 +1308,7 @@ var Select = /*#__PURE__*/function (_Component) {
1248
1308
  testId = _this$props8.testId;
1249
1309
  var _this$getComponents = this.getComponents(),
1250
1310
  Input = _this$getComponents.Input;
1251
- var _this$state4 = this.state,
1252
- inputIsHidden = _this$state4.inputIsHidden,
1253
- ariaSelection = _this$state4.ariaSelection;
1311
+ var inputIsHidden = this.state.inputIsHidden;
1254
1312
  var commonProps = this.commonProps;
1255
1313
  var id = inputId || this.getElementId('input');
1256
1314
 
@@ -1261,7 +1319,6 @@ var Select = /*#__PURE__*/function (_Component) {
1261
1319
  'aria-expanded': menuIsOpen,
1262
1320
  // TODO: aria-haspopup is implied as listbox with role="combobox" and was deprecated for aria 1.2, we still might need to keep it for back compat
1263
1321
  'aria-haspopup': this.props['UNSAFE_is_experimental_generic'] ? 'dialog' : 'listbox',
1264
- 'aria-describedby': this.props['aria-describedby'] || descriptionId,
1265
1322
  'aria-invalid': this.props['aria-invalid'] || isInvalid,
1266
1323
  'aria-label': this.props['aria-label'] || label,
1267
1324
  'aria-labelledby': this.props['aria-labelledby'] || labelId,
@@ -1272,7 +1329,7 @@ var Select = /*#__PURE__*/function (_Component) {
1272
1329
  'aria-controls': this.getElementId('listbox')
1273
1330
  }), !isSearchable && {
1274
1331
  'aria-readonly': true
1275
- }), this.calculateDescription(ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action));
1332
+ }), this.calculateDescription());
1276
1333
  if (!isSearchable) {
1277
1334
  // use a dummy input to maintain focus/blur functionality
1278
1335
  return /*#__PURE__*/React.createElement(DummyInput, _extends({
@@ -1311,7 +1368,7 @@ var Select = /*#__PURE__*/function (_Component) {
1311
1368
  }, {
1312
1369
  key: "renderPlaceholderOrValue",
1313
1370
  value: function renderPlaceholderOrValue() {
1314
- var _this3 = this;
1371
+ var _this5 = this;
1315
1372
  var _this$getComponents2 = this.getComponents(),
1316
1373
  MultiValue = _this$getComponents2.MultiValue,
1317
1374
  MultiValueContainer = _this$getComponents2.MultiValueContainer,
@@ -1327,10 +1384,10 @@ var Select = /*#__PURE__*/function (_Component) {
1327
1384
  inputValue = _this$props9.inputValue,
1328
1385
  placeholder = _this$props9.placeholder,
1329
1386
  testId = _this$props9.testId;
1330
- var _this$state5 = this.state,
1331
- selectValue = _this$state5.selectValue,
1332
- focusedValue = _this$state5.focusedValue,
1333
- isFocused = _this$state5.isFocused;
1387
+ var _this$state4 = this.state,
1388
+ selectValue = _this$state4.selectValue,
1389
+ focusedValue = _this$state4.focusedValue,
1390
+ isFocused = _this$state4.isFocused;
1334
1391
  if (!this.hasValue() || !controlShouldRenderValue) {
1335
1392
  return inputValue ? null : /*#__PURE__*/React.createElement(Placeholder, _extends({}, commonProps, {
1336
1393
  key: "placeholder",
@@ -1346,7 +1403,7 @@ var Select = /*#__PURE__*/function (_Component) {
1346
1403
  if (isMulti) {
1347
1404
  return selectValue.map(function (opt, index) {
1348
1405
  var isOptionFocused = opt === focusedValue;
1349
- var key = "".concat(_this3.getOptionLabel(opt), "-").concat(_this3.getOptionValue(opt));
1406
+ var key = "".concat(_this5.getOptionLabel(opt), "-").concat(_this5.getOptionValue(opt));
1350
1407
  return /*#__PURE__*/React.createElement(MultiValue, _extends({}, commonProps, {
1351
1408
  components: {
1352
1409
  Container: MultiValueContainer,
@@ -1359,10 +1416,10 @@ var Select = /*#__PURE__*/function (_Component) {
1359
1416
  index: index,
1360
1417
  removeProps: _objectSpread(_objectSpread({
1361
1418
  onClick: function onClick() {
1362
- return _this3.removeValue(opt);
1419
+ return _this5.removeValue(opt);
1363
1420
  },
1364
1421
  onTouchEnd: function onTouchEnd() {
1365
- return _this3.removeValue(opt);
1422
+ return _this5.removeValue(opt);
1366
1423
  },
1367
1424
  onMouseDown: function onMouseDown(e) {
1368
1425
  e.preventDefault();
@@ -1370,15 +1427,15 @@ var Select = /*#__PURE__*/function (_Component) {
1370
1427
  }, testId && {
1371
1428
  'data-testid': "".concat(testId, "-select--multivalue-").concat(index, "-remove")
1372
1429
  }), {}, {
1373
- id: "".concat(_this3.getElementId('selected-value'), "-").concat(index, "-remove")
1430
+ id: "".concat(_this5.getElementId('selected-value'), "-").concat(index, "-remove")
1374
1431
  }),
1375
1432
  data: opt,
1376
1433
  innerProps: _objectSpread(_objectSpread({}, testId && {
1377
1434
  'data-testid': "".concat(testId, "-select--multivalue-").concat(index)
1378
1435
  }), {}, {
1379
- id: "".concat(_this3.getElementId('selected-value'), "-").concat(index)
1436
+ id: "".concat(_this5.getElementId('selected-value'), "-").concat(index)
1380
1437
  })
1381
- }), _this3.formatOptionLabel(opt, 'value'));
1438
+ }), _this5.formatOptionLabel(opt, 'value'));
1382
1439
  });
1383
1440
  }
1384
1441
  if (inputValue) {
@@ -1387,7 +1444,10 @@ var Select = /*#__PURE__*/function (_Component) {
1387
1444
  var singleValue = selectValue[0];
1388
1445
  return /*#__PURE__*/React.createElement(SingleValue, _extends({}, commonProps, {
1389
1446
  data: singleValue,
1390
- isDisabled: isDisabled
1447
+ isDisabled: isDisabled,
1448
+ innerProps: {
1449
+ id: this.getElementId('single-value')
1450
+ }
1391
1451
  }), this.formatOptionLabel(singleValue, 'value'));
1392
1452
  }
1393
1453
  }, {
@@ -1481,7 +1541,7 @@ var Select = /*#__PURE__*/function (_Component) {
1481
1541
  }, {
1482
1542
  key: "renderMenu",
1483
1543
  value: function renderMenu() {
1484
- var _this4 = this;
1544
+ var _this6 = this;
1485
1545
  var _this$getComponents6 = this.getComponents(),
1486
1546
  Group = _this$getComponents6.Group,
1487
1547
  GroupHeading = _this$getComponents6.GroupHeading,
@@ -1509,8 +1569,6 @@ var Select = /*#__PURE__*/function (_Component) {
1509
1569
  noOptionsMessage = _this$props11.noOptionsMessage,
1510
1570
  onMenuScrollToTop = _this$props11.onMenuScrollToTop,
1511
1571
  onMenuScrollToBottom = _this$props11.onMenuScrollToBottom,
1512
- labelId = _this$props11.labelId,
1513
- label = _this$props11.label,
1514
1572
  testId = _this$props11.testId;
1515
1573
  if (!menuIsOpen) {
1516
1574
  return null;
@@ -1526,22 +1584,22 @@ var Select = /*#__PURE__*/function (_Component) {
1526
1584
  value = props.value;
1527
1585
  var isFocused = focusedOption === data;
1528
1586
  var onHover = isDisabled ? undefined : function () {
1529
- return _this4.onOptionHover(data);
1587
+ return _this6.onOptionHover(data);
1530
1588
  };
1531
1589
  var onSelect = isDisabled ? undefined : function () {
1532
- return _this4.selectOption(data);
1590
+ return _this6.selectOption(data);
1533
1591
  };
1534
- var optionId = "".concat(_this4.getElementId('option'), "-").concat(id);
1592
+ var optionId = "".concat(_this6.getElementId('option'), "-").concat(id);
1535
1593
  var innerProps = _objectSpread({
1536
1594
  id: optionId,
1537
1595
  onClick: onSelect,
1538
1596
  onMouseMove: onHover,
1539
1597
  onMouseOver: onHover,
1540
- role: _this4.props['UNSAFE_is_experimental_generic'] ? 'listitem' : 'option',
1541
- 'aria-selected': _this4.props['UNSAFE_is_experimental_generic'] ? undefined : isSelected,
1598
+ role: _this6.props['UNSAFE_is_experimental_generic'] ? 'listitem' : 'option',
1599
+ 'aria-selected': _this6.props['UNSAFE_is_experimental_generic'] ? undefined : isSelected,
1542
1600
  // We don't want aria-disabled if it's false. It's just noisy.
1543
- 'aria-disabled': !isDisabled && fg('design_system_select-a11y-improvement') ? undefined : isDisabled,
1544
- 'aria-describedby': fg('design_system_select-a11y-improvement') ? headingId : undefined
1601
+ 'aria-disabled': !isDisabled ? undefined : isDisabled,
1602
+ 'aria-describedby': headingId
1545
1603
  }, testId && {
1546
1604
  'data-testid': "".concat(testId, "-select--option-").concat(id)
1547
1605
  });
@@ -1555,8 +1613,8 @@ var Select = /*#__PURE__*/function (_Component) {
1555
1613
  type: type,
1556
1614
  value: value,
1557
1615
  isFocused: isFocused,
1558
- innerRef: isFocused ? _this4.getFocusedOptionRef : undefined
1559
- }), _this4.formatOptionLabel(props.data, 'menu'));
1616
+ innerRef: isFocused ? _this6.getFocusedOptionRef : undefined
1617
+ }), _this6.formatOptionLabel(props.data, 'menu'));
1560
1618
  };
1561
1619
  var menuUI;
1562
1620
  if (this.hasOptions()) {
@@ -1566,7 +1624,7 @@ var Select = /*#__PURE__*/function (_Component) {
1566
1624
  var data = item.data,
1567
1625
  options = item.options,
1568
1626
  groupIndex = item.index;
1569
- var groupId = "".concat(_this4.getElementId('group'), "-").concat(groupIndex);
1627
+ var groupId = "".concat(_this6.getElementId('group'), "-").concat(groupIndex);
1570
1628
  var headingId = "".concat(groupId, "-heading");
1571
1629
  return /*#__PURE__*/React.createElement(Group, _extends({}, commonProps, {
1572
1630
  key: groupId,
@@ -1579,7 +1637,7 @@ var Select = /*#__PURE__*/function (_Component) {
1579
1637
  }, testId && {
1580
1638
  'data-testid': "".concat(testId, "-select--group-").concat(groupIndex, "-heading")
1581
1639
  }),
1582
- label: _this4.formatGroupLabel(item.data)
1640
+ label: _this6.formatGroupLabel(item.data)
1583
1641
  }), item.options.map(function (option) {
1584
1642
  return render(option, "".concat(groupIndex, "-").concat(option.index), headingId);
1585
1643
  }));
@@ -1615,26 +1673,6 @@ var Select = /*#__PURE__*/function (_Component) {
1615
1673
  menuPosition: menuPosition,
1616
1674
  menuShouldScrollIntoView: menuShouldScrollIntoView
1617
1675
  };
1618
- var calculateListboxLabel = function calculateListboxLabel() {
1619
- var _this4$inputRef;
1620
- // First in name calculation, overwrites aria-label
1621
- if (labelId) {
1622
- return {
1623
- 'aria-labelledby': labelId
1624
- };
1625
- }
1626
- // Second in name calcuation, overwrites everything else except aria-labelledby
1627
- if (label) {
1628
- return {
1629
- 'aria-label': label
1630
- };
1631
- }
1632
- // Fallback if no label or labelId is provided, might catch label via <label for> otherwise
1633
- // will most likely not have an accessible name
1634
- return {
1635
- 'aria-labelledby': ((_this4$inputRef = _this4.inputRef) === null || _this4$inputRef === void 0 ? void 0 : _this4$inputRef.id) || _this4.getElementId('input')
1636
- };
1637
- };
1638
1676
  var menuElement = /*#__PURE__*/React.createElement(MenuPlacer, _extends({}, commonProps, menuPlacementProps), function (_ref4) {
1639
1677
  var ref = _ref4.ref,
1640
1678
  _ref4$placerProps = _ref4.placerProps,
@@ -1643,9 +1681,9 @@ var Select = /*#__PURE__*/function (_Component) {
1643
1681
  return /*#__PURE__*/React.createElement(Menu, _extends({}, commonProps, menuPlacementProps, {
1644
1682
  innerRef: ref,
1645
1683
  innerProps: _objectSpread({
1646
- onMouseDown: _this4.onMenuMouseDown,
1647
- onMouseMove: _this4.onMenuMouseMove,
1648
- id: _this4.props.components.Menu ? _this4.getElementId('listbox') : undefined
1684
+ onMouseDown: _this6.onMenuMouseDown,
1685
+ onMouseMove: _this6.onMenuMouseMove,
1686
+ id: _this6.props.components.Menu ? _this6.getElementId('listbox') : undefined
1649
1687
  }, testId && {
1650
1688
  'data-testid': "".concat(testId, "-select--listbox-container")
1651
1689
  }),
@@ -1657,23 +1695,28 @@ var Select = /*#__PURE__*/function (_Component) {
1657
1695
  onBottomArrive: onMenuScrollToBottom,
1658
1696
  lockEnabled: menuShouldBlockScroll
1659
1697
  }, function (scrollTargetRef) {
1698
+ var _this6$inputRef, _this6$inputRef2;
1660
1699
  return /*#__PURE__*/React.createElement(MenuList, _extends({}, commonProps, {
1661
1700
  innerRef: function innerRef(instance) {
1662
- _this4.getMenuListRef(instance);
1701
+ _this6.getMenuListRef(instance);
1663
1702
  scrollTargetRef(instance);
1664
1703
  },
1665
- innerProps: _objectSpread(_objectSpread({
1666
- role: _this4.props['UNSAFE_is_experimental_generic'] ? 'dialog' : 'listbox',
1667
- 'aria-label': _this4.props['UNSAFE_is_experimental_generic'] ? "".concat(_this4.props['aria-label'] || label, "-dialog") : null,
1668
- 'aria-multiselectable': (_this4.isVoiceOver || !commonProps.isMulti) && fg('design_system_select-a11y-improvement') || _this4.props['UNSAFE_is_experimental_generic'] ? undefined : commonProps.isMulti,
1669
- id: _this4.getElementId('listbox')
1704
+ innerProps: _objectSpread(_objectSpread(_objectSpread({
1705
+ role: _this6.props['UNSAFE_is_experimental_generic'] ? 'dialog' : 'listbox'
1706
+ }, _this6.props['UNSAFE_is_experimental_generic'] && {
1707
+ 'aria-labelledby': ((_this6$inputRef = _this6.inputRef) === null || _this6$inputRef === void 0 ? void 0 : _this6$inputRef.id) || _this6.getElementId('input')
1708
+ }), {}, {
1709
+ 'aria-multiselectable': !commonProps.isMulti || _this6.props['UNSAFE_is_experimental_generic'] ? undefined : commonProps.isMulti,
1710
+ id: _this6.getElementId('listbox')
1670
1711
  }, testId && {
1671
1712
  'data-testid': "".concat(testId, "-select--listbox")
1672
- }), fg('design_system_select-a11y-improvement') && calculateListboxLabel()),
1713
+ }), isSafari() && !_this6.props['UNSAFE_is_experimental_generic'] && {
1714
+ 'aria-describedby': ((_this6$inputRef2 = _this6.inputRef) === null || _this6$inputRef2 === void 0 ? void 0 : _this6$inputRef2.id) || _this6.getElementId('input')
1715
+ }),
1673
1716
  isLoading: isLoading,
1674
1717
  maxHeight: maxHeight,
1675
1718
  focusedOption: focusedOption
1676
- }), _this4.props['UNSAFE_is_experimental_generic'] ? /*#__PURE__*/React.createElement("div", {
1719
+ }), _this6.props['UNSAFE_is_experimental_generic'] ? /*#__PURE__*/React.createElement("div", {
1677
1720
  role: "list"
1678
1721
  }, menuUI) : menuUI);
1679
1722
  }));
@@ -1692,7 +1735,7 @@ var Select = /*#__PURE__*/function (_Component) {
1692
1735
  }, {
1693
1736
  key: "renderFormField",
1694
1737
  value: function renderFormField() {
1695
- var _this5 = this;
1738
+ var _this7 = this;
1696
1739
  var _this$props12 = this.props,
1697
1740
  delimiter = _this$props12.delimiter,
1698
1741
  isDisabled = _this$props12.isDisabled,
@@ -1712,7 +1755,7 @@ var Select = /*#__PURE__*/function (_Component) {
1712
1755
  if (isMulti) {
1713
1756
  if (delimiter) {
1714
1757
  var value = selectValue.map(function (opt) {
1715
- return _this5.getOptionValue(opt);
1758
+ return _this7.getOptionValue(opt);
1716
1759
  }).join(delimiter);
1717
1760
  return /*#__PURE__*/React.createElement("input", {
1718
1761
  name: name,
@@ -1725,7 +1768,7 @@ var Select = /*#__PURE__*/function (_Component) {
1725
1768
  key: "i-".concat(i),
1726
1769
  name: name,
1727
1770
  type: "hidden",
1728
- value: _this5.getOptionValue(opt)
1771
+ value: _this7.getOptionValue(opt)
1729
1772
  });
1730
1773
  }) : /*#__PURE__*/React.createElement("input", {
1731
1774
  name: name,
@@ -1747,34 +1790,32 @@ var Select = /*#__PURE__*/function (_Component) {
1747
1790
  key: "renderLiveRegion",
1748
1791
  value: function renderLiveRegion() {
1749
1792
  var commonProps = this.commonProps;
1750
- var _this$state6 = this.state,
1751
- ariaSelection = _this$state6.ariaSelection,
1752
- focusedOption = _this$state6.focusedOption,
1753
- focusedValue = _this$state6.focusedValue,
1754
- isFocused = _this$state6.isFocused,
1755
- selectValue = _this$state6.selectValue;
1793
+ var _this$state5 = this.state,
1794
+ ariaSelection = _this$state5.ariaSelection,
1795
+ isFocused = _this$state5.isFocused,
1796
+ selectValue = _this$state5.selectValue;
1756
1797
  var focusableOptions = this.getFocusableOptions();
1757
1798
  return /*#__PURE__*/React.createElement(LiveRegion, _extends({}, commonProps, {
1758
1799
  id: this.getElementId('live-region'),
1759
1800
  ariaSelection: ariaSelection,
1760
- focusedOption: focusedOption,
1761
- focusedValue: focusedValue,
1762
1801
  isFocused: isFocused,
1763
1802
  selectValue: selectValue,
1764
- focusableOptions: focusableOptions,
1765
- isAppleDevice: this.isVoiceOver
1803
+ focusableOptions: focusableOptions
1766
1804
  }));
1767
1805
  }
1768
1806
  }, {
1769
1807
  key: "renderMultiselectMessage",
1770
1808
  value: function renderMultiselectMessage() {
1809
+ // In the future, when we actually support touch devices, we'll need to update this to not be keyboard specific.
1810
+ // Also, since this is rendered onscreen, it should be transtlated automatically.
1811
+ var msg = ", multiple selections available, ".concat(this.state.selectValue.length ? 'Use left or right arrow keys to navigate selected items' : '');
1771
1812
  return (
1772
1813
  /*#__PURE__*/
1773
1814
  // eslint-disable-next-line @atlaskit/design-system/use-primitives-text
1774
1815
  React.createElement("span", {
1775
1816
  id: this.getElementId('multi-message'),
1776
1817
  hidden: true
1777
- }, ", multiple selections available,")
1818
+ }, msg)
1778
1819
  );
1779
1820
  }
1780
1821
  }, {
@@ -118,8 +118,6 @@ export interface AriaLiveMessages<Option, IsMulti extends boolean, Group extends
118
118
  onFocus?: (props: AriaOnFocusProps<Option, Group>) => string;
119
119
  }
120
120
  export declare const defaultAriaLiveMessages: {
121
- guidance: (props: AriaGuidanceProps) => string;
122
121
  onChange: <Option, IsMulti extends boolean>(props: AriaOnChangeProps<Option, IsMulti>) => string;
123
- onFocus: <Option_1, Group extends GroupBase<Option_1>>(props: AriaOnFocusProps<Option_1, Group>) => string;
124
122
  onFilter: (props: AriaOnFilterProps) => string;
125
123
  };
@@ -7,8 +7,6 @@ interface LiveRegionProps<Option, IsMulti extends boolean, Group extends GroupBa
7
7
  className?: string;
8
8
  };
9
9
  ariaSelection: AriaSelection<Option, IsMulti>;
10
- focusedOption: Option | null;
11
- focusedValue: Option | null;
12
10
  selectValue: Options<Option>;
13
11
  focusableOptions: Options<Option>;
14
12
  isFocused: boolean;
@@ -13,8 +13,6 @@ interface LiveRegionProps<Option, IsMulti extends boolean, Group extends GroupBa
13
13
  className?: string;
14
14
  };
15
15
  ariaSelection: AriaSelection<Option, IsMulti>;
16
- focusedOption: Option | null;
17
- focusedValue: Option | null;
18
16
  selectValue: Options<Option>;
19
17
  focusableOptions: Options<Option>;
20
18
  isFocused: boolean;
@@ -427,7 +427,6 @@ export interface SelectProps<Option, IsMulti extends boolean, Group extends Grou
427
427
  UNSAFE_is_experimental_generic?: boolean;
428
428
  }
429
429
  export declare const defaultProps: {
430
- 'aria-live': string | undefined;
431
430
  backspaceRemovesValue: boolean;
432
431
  blurInputOnSelect: boolean;
433
432
  captureMenuScroll: boolean;
@@ -507,7 +506,6 @@ interface CategorizedGroup<Option, Group extends GroupBase<Option>> {
507
506
  type CategorizedGroupOrOption<Option, Group extends GroupBase<Option>> = CategorizedGroup<Option, Group> | CategorizedOption<Option>;
508
507
  export default class Select<Option = unknown, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>> extends Component<SelectProps<Option, IsMulti, Group>, State<Option, IsMulti, Group>> {
509
508
  static defaultProps: {
510
- 'aria-live': string | undefined;
511
509
  backspaceRemovesValue: boolean;
512
510
  blurInputOnSelect: boolean;
513
511
  captureMenuScroll: boolean;
@@ -558,7 +556,6 @@ export default class Select<Option = unknown, IsMulti extends boolean = false, G
558
556
  openAfterFocus: boolean;
559
557
  scrollToFocusedOptionOnUpdate: boolean;
560
558
  userIsDragging?: boolean;
561
- isVoiceOver: boolean;
562
559
  controlRef: HTMLDivElement | null;
563
560
  getControlRef: RefCallback<HTMLDivElement>;
564
561
  focusedOptionRef: HTMLDivElement | null;
@@ -592,6 +589,8 @@ export default class Select<Option = unknown, IsMulti extends boolean = false, G
592
589
  focus: () => void;
593
590
  blur: () => void;
594
591
  openMenu(focusOption: 'first' | 'last'): void;
592
+ updateInputLabel(inputLabel?: string): void;
593
+ calculateInputLabel(focusedOption: Option, optionIndex: number): string;
595
594
  focusValue(direction: 'previous' | 'next'): void;
596
595
  focusOption(direction?: FocusDirection): void;
597
596
  onChange: (newValue: OnChangeValue<Option, IsMulti>, actionMeta: ActionMeta<Option>) => void;
@@ -622,7 +621,7 @@ export default class Select<Option = unknown, IsMulti extends boolean = false, G
622
621
  getOptionValue: (data: Option) => string;
623
622
  getStyles: <Key extends keyof StylesProps<Option, IsMulti, Group>>(key: Key, props: StylesProps<Option, IsMulti, Group>[Key]) => Record<string, any>;
624
623
  getClassNames: <Key extends keyof StylesProps<Option, IsMulti, Group>>(key: Key, props: StylesProps<Option, IsMulti, Group>[Key]) => string | undefined;
625
- getElementId: (element: 'group' | 'input' | 'listbox' | 'option' | 'placeholder' | 'live-region' | 'multi-message' | 'selected-value') => string;
624
+ getElementId: (element: 'group' | 'input' | 'listbox' | 'option' | 'placeholder' | 'live-region' | 'multi-message' | 'single-value' | 'selected-value') => string;
626
625
  getComponents: () => {
627
626
  ClearIndicator: <Option_1, IsMulti_1 extends boolean, Group_1 extends GroupBase<Option_1>>(props: import(".").ClearIndicatorProps<Option_1, IsMulti_1, Group_1>) => React.JSX.Element;
628
627
  Control: <Option_2, IsMulti_2 extends boolean, Group_2 extends GroupBase<Option_2>>(props: import(".").ControlProps<Option_2, IsMulti_2, Group_2>) => React.JSX.Element;
@@ -660,9 +659,9 @@ export default class Select<Option = unknown, IsMulti extends boolean = false, G
660
659
  filterOption(option: FilterOptionOption<Option>, inputValue: string): boolean;
661
660
  formatOptionLabel(data: Option, context: FormatOptionLabelContext): ReactNode;
662
661
  formatGroupLabel(data: Group): React.ReactNode;
663
- calculateDescription(action?: String): {
662
+ calculateDescription(): {
664
663
  'aria-describedby': string;
665
- } | undefined;
664
+ };
666
665
  onMenuMouseDown: MouseEventHandler<HTMLDivElement>;
667
666
  onMenuMouseMove: MouseEventHandler<HTMLDivElement>;
668
667
  onControlMouseDown: (event: React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>) => void;
@@ -118,8 +118,6 @@ export interface AriaLiveMessages<Option, IsMulti extends boolean, Group extends
118
118
  onFocus?: (props: AriaOnFocusProps<Option, Group>) => string;
119
119
  }
120
120
  export declare const defaultAriaLiveMessages: {
121
- guidance: (props: AriaGuidanceProps) => string;
122
121
  onChange: <Option, IsMulti extends boolean>(props: AriaOnChangeProps<Option, IsMulti>) => string;
123
- onFocus: <Option_1, Group extends GroupBase<Option_1>>(props: AriaOnFocusProps<Option_1, Group>) => string;
124
122
  onFilter: (props: AriaOnFilterProps) => string;
125
123
  };
@@ -7,8 +7,6 @@ interface LiveRegionProps<Option, IsMulti extends boolean, Group extends GroupBa
7
7
  className?: string;
8
8
  };
9
9
  ariaSelection: AriaSelection<Option, IsMulti>;
10
- focusedOption: Option | null;
11
- focusedValue: Option | null;
12
10
  selectValue: Options<Option>;
13
11
  focusableOptions: Options<Option>;
14
12
  isFocused: boolean;
@@ -13,8 +13,6 @@ interface LiveRegionProps<Option, IsMulti extends boolean, Group extends GroupBa
13
13
  className?: string;
14
14
  };
15
15
  ariaSelection: AriaSelection<Option, IsMulti>;
16
- focusedOption: Option | null;
17
- focusedValue: Option | null;
18
16
  selectValue: Options<Option>;
19
17
  focusableOptions: Options<Option>;
20
18
  isFocused: boolean;