@atlaskit/react-select 1.4.0 → 1.4.2

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.
Files changed (64) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/accessibility/index.js +9 -7
  3. package/dist/cjs/components/containers.js +9 -7
  4. package/dist/cjs/components/control.js +58 -13
  5. package/dist/cjs/components/group.js +11 -11
  6. package/dist/cjs/components/indicators.js +39 -34
  7. package/dist/cjs/components/input.js +1 -1
  8. package/dist/cjs/components/internal/a11y-text.js +2 -0
  9. package/dist/cjs/components/live-region.js +6 -3
  10. package/dist/cjs/components/menu.js +4 -5
  11. package/dist/cjs/components/multi-value.js +86 -30
  12. package/dist/cjs/components/option.js +38 -13
  13. package/dist/cjs/components/placeholder.js +3 -6
  14. package/dist/cjs/components/single-value.js +3 -6
  15. package/dist/cjs/select.js +105 -54
  16. package/dist/es2019/accessibility/index.js +9 -7
  17. package/dist/es2019/components/containers.js +8 -8
  18. package/dist/es2019/components/control.js +71 -24
  19. package/dist/es2019/components/group.js +10 -18
  20. package/dist/es2019/components/indicators.js +25 -28
  21. package/dist/es2019/components/input.js +1 -1
  22. package/dist/es2019/components/internal/a11y-text.js +2 -0
  23. package/dist/es2019/components/live-region.js +6 -2
  24. package/dist/es2019/components/menu.js +6 -11
  25. package/dist/es2019/components/multi-value.js +89 -30
  26. package/dist/es2019/components/option.js +48 -22
  27. package/dist/es2019/components/placeholder.js +3 -7
  28. package/dist/es2019/components/single-value.js +3 -5
  29. package/dist/es2019/select.js +74 -24
  30. package/dist/esm/accessibility/index.js +9 -7
  31. package/dist/esm/components/containers.js +9 -7
  32. package/dist/esm/components/control.js +58 -13
  33. package/dist/esm/components/group.js +11 -11
  34. package/dist/esm/components/indicators.js +39 -34
  35. package/dist/esm/components/input.js +1 -1
  36. package/dist/esm/components/internal/a11y-text.js +2 -0
  37. package/dist/esm/components/live-region.js +6 -2
  38. package/dist/esm/components/menu.js +4 -5
  39. package/dist/esm/components/multi-value.js +86 -30
  40. package/dist/esm/components/option.js +38 -13
  41. package/dist/esm/components/placeholder.js +3 -6
  42. package/dist/esm/components/single-value.js +3 -6
  43. package/dist/esm/select.js +105 -53
  44. package/dist/types/components/containers.d.ts +5 -1
  45. package/dist/types/components/control.d.ts +10 -1
  46. package/dist/types/components/group.d.ts +2 -2
  47. package/dist/types/components/indicators.d.ts +16 -4
  48. package/dist/types/components/menu.d.ts +1 -1
  49. package/dist/types/components/multi-value.d.ts +3 -3
  50. package/dist/types/components/option.d.ts +1 -1
  51. package/dist/types/components/placeholder.d.ts +1 -1
  52. package/dist/types/components/single-value.d.ts +1 -1
  53. package/dist/types/select.d.ts +13 -4
  54. package/dist/types-ts4.5/components/containers.d.ts +5 -1
  55. package/dist/types-ts4.5/components/control.d.ts +10 -1
  56. package/dist/types-ts4.5/components/group.d.ts +2 -2
  57. package/dist/types-ts4.5/components/indicators.d.ts +16 -4
  58. package/dist/types-ts4.5/components/menu.d.ts +1 -1
  59. package/dist/types-ts4.5/components/multi-value.d.ts +3 -3
  60. package/dist/types-ts4.5/components/option.d.ts +1 -1
  61. package/dist/types-ts4.5/components/placeholder.d.ts +1 -1
  62. package/dist/types-ts4.5/components/single-value.d.ts +1 -1
  63. package/dist/types-ts4.5/select.d.ts +13 -4
  64. package/package.json +6 -2
@@ -7,7 +7,10 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.optionCSS = exports.default = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var _react = require("@emotion/react");
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
11
+ var _helpers = require("../accessibility/helpers");
10
12
  var _utils = require("../utils");
13
+ var _a11yText = _interopRequireDefault(require("./internal/a11y-text"));
11
14
  /**
12
15
  * @jsxRuntime classic
13
16
  * @jsx jsx
@@ -16,24 +19,45 @@ var _utils = require("../utils");
16
19
  var optionCSS = exports.optionCSS = function optionCSS(_ref) {
17
20
  var isDisabled = _ref.isDisabled,
18
21
  isFocused = _ref.isFocused,
19
- isSelected = _ref.isSelected,
20
- _ref$theme = _ref.theme,
21
- spacing = _ref$theme.spacing,
22
- colors = _ref$theme.colors;
22
+ isSelected = _ref.isSelected;
23
+ var color = "var(--ds-text, #172B4D)";
24
+ if (isDisabled) {
25
+ color = "var(--ds-text-disabled, #091E424F)";
26
+ } else if (isSelected) {
27
+ color = "var(--ds-text-selected, #0C66E4)";
28
+ }
29
+ var boxShadow;
30
+ var backgroundColor;
31
+ if (isDisabled) {
32
+ backgroundColor = undefined;
33
+ } else if (isSelected && isFocused) {
34
+ backgroundColor = "var(--ds-background-selected-hovered, #CCE0FF)";
35
+ } else if (isSelected) {
36
+ backgroundColor = "var(--ds-background-selected, #E9F2FF)";
37
+ } else if (isFocused) {
38
+ backgroundColor = "var(--ds-background-neutral-subtle-hovered, #091E420F)";
39
+ }
40
+ if (!isDisabled && (isFocused || isSelected)) {
41
+ boxShadow = "inset 2px 0px 0px ".concat("var(--ds-border-selected, #0C66E4)");
42
+ }
43
+ var cursor = isDisabled ? 'not-allowed' : 'default';
23
44
  return {
24
45
  label: 'option',
25
- cursor: 'default',
26
46
  display: 'block',
27
47
  fontSize: 'inherit',
28
48
  width: '100%',
29
49
  userSelect: 'none',
30
50
  WebkitTapHighlightColor: 'rgba(0, 0, 0, 0)',
31
- backgroundColor: isSelected ? colors.primary : isFocused ? colors.primary25 : 'transparent',
32
- color: isDisabled ? colors.neutral20 : isSelected ? colors.neutral0 : 'inherit',
33
- padding: "".concat(spacing.baseUnit * 2, "px ").concat(spacing.baseUnit * 3, "px"),
34
- // provide some affordance on touch devices
51
+ padding: "var(--ds-space-075, 6px)".concat(" ", "var(--ds-space-150, 12px)"),
52
+ backgroundColor: backgroundColor,
53
+ color: color,
54
+ cursor: cursor,
55
+ boxShadow: boxShadow,
35
56
  ':active': {
36
- backgroundColor: !isDisabled ? isSelected ? colors.primary : colors.primary50 : undefined
57
+ backgroundColor: !isDisabled ? isSelected ? "var(--ds-background-selected-pressed, #85B8FF)" : "var(--ds-background-neutral-subtle-pressed, #091E4224)" : undefined
58
+ },
59
+ '@media screen and (-ms-high-contrast: active)': {
60
+ borderLeft: !isDisabled && (isFocused || isSelected) ? '2px solid transparent' : ''
37
61
  }
38
62
  };
39
63
  };
@@ -44,17 +68,18 @@ var Option = function Option(props) {
44
68
  isSelected = props.isSelected,
45
69
  innerRef = props.innerRef,
46
70
  innerProps = props.innerProps;
71
+ // eslint-disable-next-line @atlaskit/platform/ensure-feature-flag-prefix
72
+ var isVoiceOver = (0, _helpers.isAppleDevice)() && (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement');
47
73
  return (0, _react.jsx)("div", (0, _extends2.default)({}, (0, _utils.getStyleProps)(props, 'option', {
48
74
  option: true,
49
75
  'option--is-disabled': isDisabled,
50
76
  'option--is-focused': isFocused,
51
77
  'option--is-selected': isSelected
52
78
  }), {
53
- ref: innerRef,
54
- "aria-disabled": isDisabled
79
+ ref: innerRef
55
80
  }, innerProps, {
56
81
  tabIndex: -1
57
- }), children);
82
+ }), children, isVoiceOver && (isSelected || isDisabled) && (0, _react.jsx)(_a11yText.default, null, "".concat(isSelected ? ',selected' : '').concat(isDisabled ? ',dimmed' : '')));
58
83
  };
59
84
 
60
85
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
@@ -14,15 +14,12 @@ var _utils = require("../utils");
14
14
  */
15
15
 
16
16
  var placeholderCSS = exports.placeholderCSS = function placeholderCSS(_ref) {
17
- var _ref$theme = _ref.theme,
18
- spacing = _ref$theme.spacing,
19
- colors = _ref$theme.colors;
17
+ var isDisabled = _ref.isDisabled;
20
18
  return {
21
19
  label: 'placeholder',
22
20
  gridArea: '1 / 1 / 2 / 3',
23
- color: colors.neutral50,
24
- marginLeft: spacing.baseUnit / 2,
25
- marginRight: spacing.baseUnit / 2
21
+ margin: "0 ".concat("var(--ds-space-025, 2px)"),
22
+ color: isDisabled ? "var(--ds-text-disabled, #091E424F)" : "var(--ds-text-subtlest, #626F86)"
26
23
  };
27
24
  };
28
25
  var Placeholder = function Placeholder(props) {
@@ -15,9 +15,7 @@ var _utils = require("../utils");
15
15
 
16
16
  var css = exports.css = function css(_ref) {
17
17
  var isDisabled = _ref.isDisabled,
18
- _ref$theme = _ref.theme,
19
- spacing = _ref$theme.spacing,
20
- colors = _ref$theme.colors;
18
+ spacing = _ref.theme.spacing;
21
19
  return {
22
20
  label: 'singleValue',
23
21
  gridArea: '1 / 1 / 2 / 3',
@@ -25,9 +23,8 @@ var css = exports.css = function css(_ref) {
25
23
  overflow: 'hidden',
26
24
  textOverflow: 'ellipsis',
27
25
  whiteSpace: 'nowrap',
28
- color: isDisabled ? colors.neutral40 : colors.neutral80,
29
- marginLeft: spacing.baseUnit / 2,
30
- marginRight: spacing.baseUnit / 2
26
+ margin: "0 ".concat("var(--ds-space-025, 2px)"),
27
+ color: isDisabled ? "var(--ds-text-disabled, #091E424F)" : "var(--ds-text, #172B4D)"
31
28
  };
32
29
  };
33
30
  var SingleValue = function SingleValue(props) {
@@ -32,9 +32,10 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
32
32
  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; }
33
33
  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) { (0, _defineProperty2.default)(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; }
34
34
  function _createSuper(t) { var r = _isNativeReflectConstruct(); return function () { var e, o = (0, _getPrototypeOf2.default)(t); if (r) { var s = (0, _getPrototypeOf2.default)(this).constructor; e = Reflect.construct(o, arguments, s); } else e = o.apply(this, arguments); return (0, _possibleConstructorReturn2.default)(this, e); }; }
35
- function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
35
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /* eslint-disable @atlaskit/platform/ensure-feature-flag-prefix */
36
36
  var defaultProps = exports.defaultProps = {
37
- 'aria-live': 'polite',
37
+ // aria-live is by default with the live region so we don't need it
38
+ 'aria-live': (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? undefined : 'polite',
38
39
  backspaceRemovesValue: true,
39
40
  blurInputOnSelect: (0, _utils.isTouchCapable)(),
40
41
  captureMenuScroll: !(0, _utils.isTouchCapable)(),
@@ -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, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? (0, _helpers.isSafari)() : (0, _helpers.isAppleDevice)());
262
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isVoiceOver", (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') && (0, _helpers.isAppleDevice)());
262
263
  // Refs
263
264
  // ------------------------------
264
265
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "controlRef", null);
@@ -759,6 +760,7 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
759
760
  prevInputValue: inputValue
760
761
  });
761
762
  _this.onMenuClose();
763
+ (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') && event.stopPropagation(); // keep ESC on select from dismissing parent layers
762
764
  } else if (isClearable && escapeClearsValue) {
763
765
  _this.clearValue();
764
766
  }
@@ -1162,6 +1164,27 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1162
1164
  value: function formatGroupLabel(data) {
1163
1165
  return this.props.formatGroupLabel(data);
1164
1166
  }
1167
+ }, {
1168
+ key: "calculateDescription",
1169
+ value: function calculateDescription(action) {
1170
+ var descriptionProp = this.props['aria-describedby'] || this.props['descriptionId'];
1171
+ var isMulti = this.props.isMulti;
1172
+ var selectValue = this.state.selectValue;
1173
+ var defaultDescription = selectValue.length ? this.getElementId('live-region') : this.getElementId('placeholder');
1174
+ if (selectValue.length && action !== 'initial-input-focus') {
1175
+ return;
1176
+ }
1177
+ if (isMulti && (0, _helpers.isAppleDevice)() && !(0, _helpers.isSafari)()) {
1178
+ // chrome only friends
1179
+ return {
1180
+ 'aria-describedby': descriptionProp ? [descriptionProp, defaultDescription, this.getElementId('multi-message')].join(' ') : [defaultDescription, this.getElementId('multi-message')].join(' ')
1181
+ };
1182
+ } else {
1183
+ return {
1184
+ 'aria-describedby': descriptionProp ? [descriptionProp, defaultDescription].join(' ') : defaultDescription
1185
+ };
1186
+ }
1187
+ }
1165
1188
  }, {
1166
1189
  key: "startListeningComposition",
1167
1190
  value:
@@ -1245,30 +1268,28 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1245
1268
  ariaSelection = _this$state4.ariaSelection;
1246
1269
  var commonProps = this.commonProps;
1247
1270
  var id = inputId || this.getElementId('input');
1248
- var description = this.props['aria-describedby'] || descriptionId;
1249
1271
 
1250
1272
  // aria attributes makes the JSX "noisy", separated for clarity
1251
1273
  var ariaAttributes = _objectSpread(_objectSpread(_objectSpread({
1252
1274
  'aria-autocomplete': 'both',
1253
1275
  'aria-errormessage': this.props['aria-errormessage'],
1254
1276
  'aria-expanded': menuIsOpen,
1277
+ // 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
1255
1278
  'aria-haspopup': 'listbox',
1256
- 'aria-describedby': description,
1279
+ 'aria-describedby': this.props['aria-describedby'] || descriptionId,
1257
1280
  'aria-invalid': this.props['aria-invalid'] || isInvalid,
1258
1281
  'aria-label': this.props['aria-label'] || label,
1259
1282
  'aria-labelledby': this.props['aria-labelledby'] || labelId,
1260
1283
  'aria-required': required || isRequired,
1261
1284
  role: 'combobox',
1262
- 'aria-activedescendant': this.state.focusedOptionId || undefined
1285
+ 'aria-activedescendant': this.state.focusedOptionId || undefined,
1286
+ // Safari needs aria-owns in order for aria-activedescendant to work properly
1287
+ 'aria-owns': (0, _helpers.isSafari)() && (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? this.getElementId('listbox') : undefined
1263
1288
  }, menuIsOpen && {
1264
1289
  'aria-controls': this.getElementId('listbox')
1265
1290
  }), !isSearchable && {
1266
1291
  'aria-readonly': true
1267
- }), this.hasValue() ? (ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action) === 'initial-input-focus' && {
1268
- 'aria-describedby': description ? [description, this.getElementId('live-region')].join(' ') : this.getElementId('live-region')
1269
- } : {
1270
- 'aria-describedby': description ? [description, this.getElementId('placeholder')].join(' ') : this.getElementId('placeholder')
1271
- });
1292
+ }), this.calculateDescription(ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action));
1272
1293
  if (!isSearchable) {
1273
1294
  // use a dummy input to maintain focus/blur functionality
1274
1295
  return /*#__PURE__*/_react.default.createElement(_internal.DummyInput, (0, _extends2.default)({
@@ -1381,7 +1402,8 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1381
1402
  var _this$props10 = this.props,
1382
1403
  clearControlLabel = _this$props10.clearControlLabel,
1383
1404
  isDisabled = _this$props10.isDisabled,
1384
- isLoading = _this$props10.isLoading;
1405
+ isLoading = _this$props10.isLoading,
1406
+ spacing = _this$props10.spacing;
1385
1407
  var isFocused = this.state.isFocused;
1386
1408
  if (!this.isClearable() || !ClearIndicator || isDisabled || !this.hasValue() || isLoading) {
1387
1409
  return null;
@@ -1391,11 +1413,13 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1391
1413
  onTouchEnd: this.onClearIndicatorTouchEnd,
1392
1414
  'aria-hidden': 'true'
1393
1415
  };
1416
+ var isCompact = spacing === 'compact';
1394
1417
  return /*#__PURE__*/_react.default.createElement(ClearIndicator, (0, _extends2.default)({
1395
1418
  clearControlLabel: clearControlLabel
1396
1419
  }, commonProps, {
1397
1420
  innerProps: innerProps,
1398
- isFocused: isFocused
1421
+ isFocused: isFocused,
1422
+ isCompact: isCompact
1399
1423
  }));
1400
1424
  }
1401
1425
  }, {
@@ -1406,18 +1430,21 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1406
1430
  var commonProps = this.commonProps;
1407
1431
  var _this$props11 = this.props,
1408
1432
  isDisabled = _this$props11.isDisabled,
1409
- isLoading = _this$props11.isLoading;
1433
+ isLoading = _this$props11.isLoading,
1434
+ spacing = _this$props11.spacing;
1410
1435
  var isFocused = this.state.isFocused;
1411
1436
  if (!LoadingIndicator || !isLoading) {
1412
1437
  return null;
1413
1438
  }
1439
+ var isCompact = spacing === 'compact';
1414
1440
  var innerProps = {
1415
1441
  'aria-hidden': 'true'
1416
1442
  };
1417
1443
  return /*#__PURE__*/_react.default.createElement(LoadingIndicator, (0, _extends2.default)({}, commonProps, {
1418
1444
  innerProps: innerProps,
1419
1445
  isDisabled: isDisabled,
1420
- isFocused: isFocused
1446
+ isFocused: isFocused,
1447
+ isCompact: isCompact
1421
1448
  }));
1422
1449
  }
1423
1450
  }, {
@@ -1448,8 +1475,11 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1448
1475
  return null;
1449
1476
  }
1450
1477
  var commonProps = this.commonProps;
1451
- var isDisabled = this.props.isDisabled;
1478
+ var _this$props12 = this.props,
1479
+ isDisabled = _this$props12.isDisabled,
1480
+ spacing = _this$props12.spacing;
1452
1481
  var isFocused = this.state.isFocused;
1482
+ var isCompact = spacing === 'compact';
1453
1483
  var innerProps = {
1454
1484
  onMouseDown: this.onDropdownIndicatorMouseDown,
1455
1485
  onTouchEnd: this.onDropdownIndicatorTouchEnd,
@@ -1458,7 +1488,8 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1458
1488
  return /*#__PURE__*/_react.default.createElement(DropdownIndicator, (0, _extends2.default)({}, commonProps, {
1459
1489
  innerProps: innerProps,
1460
1490
  isDisabled: isDisabled,
1461
- isFocused: isFocused
1491
+ isFocused: isFocused,
1492
+ isCompact: isCompact
1462
1493
  }));
1463
1494
  }
1464
1495
  }, {
@@ -1476,24 +1507,24 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1476
1507
  Option = _this$getComponents7.Option;
1477
1508
  var commonProps = this.commonProps;
1478
1509
  var focusedOption = this.state.focusedOption;
1479
- var _this$props12 = this.props,
1480
- captureMenuScroll = _this$props12.captureMenuScroll,
1481
- inputValue = _this$props12.inputValue,
1482
- isLoading = _this$props12.isLoading,
1483
- loadingMessage = _this$props12.loadingMessage,
1484
- minMenuHeight = _this$props12.minMenuHeight,
1485
- maxMenuHeight = _this$props12.maxMenuHeight,
1486
- menuIsOpen = _this$props12.menuIsOpen,
1487
- menuPlacement = _this$props12.menuPlacement,
1488
- menuPosition = _this$props12.menuPosition,
1489
- menuPortalTarget = _this$props12.menuPortalTarget,
1490
- menuShouldBlockScroll = _this$props12.menuShouldBlockScroll,
1491
- menuShouldScrollIntoView = _this$props12.menuShouldScrollIntoView,
1492
- noOptionsMessage = _this$props12.noOptionsMessage,
1493
- onMenuScrollToTop = _this$props12.onMenuScrollToTop,
1494
- onMenuScrollToBottom = _this$props12.onMenuScrollToBottom,
1495
- labelId = _this$props12.labelId,
1496
- label = _this$props12.label;
1510
+ var _this$props13 = this.props,
1511
+ captureMenuScroll = _this$props13.captureMenuScroll,
1512
+ inputValue = _this$props13.inputValue,
1513
+ isLoading = _this$props13.isLoading,
1514
+ loadingMessage = _this$props13.loadingMessage,
1515
+ minMenuHeight = _this$props13.minMenuHeight,
1516
+ maxMenuHeight = _this$props13.maxMenuHeight,
1517
+ menuIsOpen = _this$props13.menuIsOpen,
1518
+ menuPlacement = _this$props13.menuPlacement,
1519
+ menuPosition = _this$props13.menuPosition,
1520
+ menuPortalTarget = _this$props13.menuPortalTarget,
1521
+ menuShouldBlockScroll = _this$props13.menuShouldBlockScroll,
1522
+ menuShouldScrollIntoView = _this$props13.menuShouldScrollIntoView,
1523
+ noOptionsMessage = _this$props13.noOptionsMessage,
1524
+ onMenuScrollToTop = _this$props13.onMenuScrollToTop,
1525
+ onMenuScrollToBottom = _this$props13.onMenuScrollToBottom,
1526
+ labelId = _this$props13.labelId,
1527
+ label = _this$props13.label;
1497
1528
  if (!menuIsOpen) {
1498
1529
  return null;
1499
1530
  }
@@ -1520,7 +1551,10 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1520
1551
  onMouseMove: onHover,
1521
1552
  onMouseOver: onHover,
1522
1553
  role: 'option',
1523
- 'aria-selected': !commonProps.isMulti && (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? isSelected || undefined : isSelected,
1554
+ // We don't want aria-selected on Apple devices or if it's false. It does nasty things.
1555
+ 'aria-selected': (!commonProps.isMulti || _this4.isVoiceOver || !isSelected) && (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? undefined : isSelected,
1556
+ // We don't want aria-disabled on Apple devices or if it's false. It's just noisy.
1557
+ 'aria-disabled': ((0, _helpers.isAppleDevice)() || !isDisabled) && (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? undefined : isDisabled,
1524
1558
  'aria-describedby': (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? headingId : undefined
1525
1559
  };
1526
1560
  return /*#__PURE__*/_react.default.createElement(Option, (0, _extends2.default)({}, commonProps, {
@@ -1614,12 +1648,11 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1614
1648
  },
1615
1649
  innerProps: _objectSpread({
1616
1650
  role: 'listbox',
1617
- // don't add aria-multiselectable when ff is on and the value is false
1618
- 'aria-multiselectable': (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? commonProps.isMulti || undefined : commonProps.isMulti,
1651
+ 'aria-multiselectable': (_this4.isVoiceOver || !commonProps.isMulti) && (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') ? undefined : commonProps.isMulti,
1619
1652
  id: _this4.getElementId('listbox')
1620
1653
  }, (0, _platformFeatureFlags.fg)('design_system_select-a11y-improvement') && {
1621
1654
  'aria-label': label,
1622
- 'aria-labelledby': labelId
1655
+ 'aria-labelledby': "".concat(labelId || _this4.getElementId('input'), " ").concat(commonProps.isMulti && (0, _helpers.isSafari)() ? _this4.getElementId('multi-message') : '')
1623
1656
  }),
1624
1657
  isLoading: isLoading,
1625
1658
  maxHeight: maxHeight,
@@ -1642,12 +1675,12 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1642
1675
  key: "renderFormField",
1643
1676
  value: function renderFormField() {
1644
1677
  var _this5 = this;
1645
- var _this$props13 = this.props,
1646
- delimiter = _this$props13.delimiter,
1647
- isDisabled = _this$props13.isDisabled,
1648
- isMulti = _this$props13.isMulti,
1649
- required = _this$props13.required,
1650
- name = _this$props13.name;
1678
+ var _this$props14 = this.props,
1679
+ delimiter = _this$props14.delimiter,
1680
+ isDisabled = _this$props14.isDisabled,
1681
+ isMulti = _this$props14.isMulti,
1682
+ required = _this$props14.required,
1683
+ name = _this$props14.name;
1651
1684
  var selectValue = this.state.selectValue;
1652
1685
  if (required && !this.hasValue() && !isDisabled) {
1653
1686
  return /*#__PURE__*/_react.default.createElement(_internal.RequiredInput, {
@@ -1711,9 +1744,17 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1711
1744
  isFocused: isFocused,
1712
1745
  selectValue: selectValue,
1713
1746
  focusableOptions: focusableOptions,
1714
- isAppleDevice: this.isAppleDevice
1747
+ isAppleDevice: this.isVoiceOver
1715
1748
  }));
1716
1749
  }
1750
+ }, {
1751
+ key: "renderMultiselectMessage",
1752
+ value: function renderMultiselectMessage() {
1753
+ return /*#__PURE__*/_react.default.createElement("span", {
1754
+ id: this.getElementId('multi-message'),
1755
+ hidden: true
1756
+ }, ", multiple selections available,");
1757
+ }
1717
1758
  }, {
1718
1759
  key: "render",
1719
1760
  value: function render() {
@@ -1722,13 +1763,19 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1722
1763
  IndicatorsContainer = _this$getComponents8.IndicatorsContainer,
1723
1764
  SelectContainer = _this$getComponents8.SelectContainer,
1724
1765
  ValueContainer = _this$getComponents8.ValueContainer;
1725
- var _this$props14 = this.props,
1726
- className = _this$props14.className,
1727
- id = _this$props14.id,
1728
- isDisabled = _this$props14.isDisabled,
1729
- menuIsOpen = _this$props14.menuIsOpen;
1766
+ var _this$props15 = this.props,
1767
+ className = _this$props15.className,
1768
+ id = _this$props15.id,
1769
+ isDisabled = _this$props15.isDisabled,
1770
+ menuIsOpen = _this$props15.menuIsOpen,
1771
+ isInvalid = _this$props15.isInvalid,
1772
+ _this$props15$appeara = _this$props15.appearance,
1773
+ appearance = _this$props15$appeara === void 0 ? 'default' : _this$props15$appeara,
1774
+ _this$props15$spacing = _this$props15.spacing,
1775
+ spacing = _this$props15$spacing === void 0 ? 'default' : _this$props15$spacing;
1730
1776
  var isFocused = this.state.isFocused;
1731
1777
  var commonProps = this.commonProps = this.getCommonProps();
1778
+ var isCompact = spacing === 'compact';
1732
1779
  return /*#__PURE__*/_react.default.createElement(SelectContainer, (0, _extends2.default)({}, commonProps, {
1733
1780
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
1734
1781
  className: className,
@@ -1738,17 +1785,21 @@ var Select = exports.default = /*#__PURE__*/function (_Component) {
1738
1785
  },
1739
1786
  isDisabled: isDisabled,
1740
1787
  isFocused: isFocused
1741
- }), this.renderLiveRegion(), /*#__PURE__*/_react.default.createElement(Control, (0, _extends2.default)({}, commonProps, {
1788
+ }), this.renderLiveRegion(), commonProps.isMulti && this.isVoiceOver && this.renderMultiselectMessage(), /*#__PURE__*/_react.default.createElement(Control, (0, _extends2.default)({}, commonProps, {
1742
1789
  innerRef: this.getControlRef,
1743
1790
  innerProps: {
1744
1791
  onMouseDown: this.onControlMouseDown,
1745
1792
  onTouchEnd: this.onControlTouchEnd
1746
1793
  },
1794
+ appearance: appearance,
1795
+ isInvalid: isInvalid,
1747
1796
  isDisabled: isDisabled,
1748
1797
  isFocused: isFocused,
1749
- menuIsOpen: menuIsOpen
1798
+ menuIsOpen: menuIsOpen,
1799
+ isCompact: isCompact
1750
1800
  }), /*#__PURE__*/_react.default.createElement(ValueContainer, (0, _extends2.default)({}, commonProps, {
1751
- isDisabled: isDisabled
1801
+ isDisabled: isDisabled,
1802
+ isCompact: isCompact
1752
1803
  }), this.renderPlaceholderOrValue(), this.renderInput()), /*#__PURE__*/_react.default.createElement(IndicatorsContainer, (0, _extends2.default)({}, commonProps, {
1753
1804
  isDisabled: isDisabled
1754
1805
  }), this.renderClearIndicator(), this.renderLoadingIndicator(), this.renderIndicatorSeparator(), this.renderDropdownIndicator())), this.renderMenu(), this.renderFormField());
@@ -1,3 +1,5 @@
1
+ /* eslint-disable @atlaskit/platform/ensure-feature-flag-prefix */
2
+
1
3
  import { fg } from '@atlaskit/platform-feature-flags';
2
4
  export const defaultAriaLiveMessages = {
3
5
  guidance: props => {
@@ -30,11 +32,12 @@ export const defaultAriaLiveMessages = {
30
32
  case 'deselect-option':
31
33
  case 'pop-value':
32
34
  case 'remove-value':
33
- return `option ${label}, deselected.`;
35
+ return label.length && fg('design_system_select-a11y-improvement') || !fg('design_system_select-a11y-improvement') ? `option ${label}, deselected` : '';
36
+ // TODO: this should be handled on backspace|delete if no value, but doing it here first
34
37
  case 'clear':
35
38
  return 'All selected options have been cleared.';
36
39
  case 'initial-input-focus':
37
- return `option${labels.length > 1 ? 's' : ''} ${labels.join(',')}, selected.`;
40
+ return label.length && fg('design_system_select-a11y-improvement') || !fg('design_system_select-a11y-improvement') ? `option${labels.length > 1 ? 's' : ''} ${labels.join(',')}, selected.` : '';
38
41
  case 'select-option':
39
42
  return isDisabled ? `option ${label} is disabled. Select another option.` : `option ${label}, selected.`;
40
43
  default:
@@ -48,7 +51,6 @@ export const defaultAriaLiveMessages = {
48
51
  options,
49
52
  label = '',
50
53
  selectValue,
51
- isMulti,
52
54
  isDisabled,
53
55
  isSelected
54
56
  } = props;
@@ -56,11 +58,11 @@ export const defaultAriaLiveMessages = {
56
58
  if (context === 'value' && selectValue) {
57
59
  return `value ${label} focused, ${getArrayIndex(selectValue, focused)}.`;
58
60
  }
59
- if (context === 'menu') {
61
+
62
+ // No longer needed after fg('design_system_select-a11y-improvement') is cleaned up
63
+ if (context === 'menu' && !fg('design_system_select-a11y-improvement')) {
60
64
  const disabled = isDisabled ? ' disabled' : '';
61
- // don't announce not selected for single selection
62
- const notSelectedStatus = !isMulti && fg('design_system_select-a11y-improvement') ? '' : ' not selected';
63
- const status = `${isSelected ? ' selected' : notSelectedStatus}${disabled}`;
65
+ const status = `${isSelected ? ' selected' : ' not selected'}${disabled}`;
64
66
  return `${label}${status}, ${getArrayIndex(options, focused)}, completion selected`;
65
67
  }
66
68
  return '';
@@ -17,9 +17,10 @@ export const containerCSS = ({
17
17
  }) => ({
18
18
  label: 'container',
19
19
  direction: isRtl ? 'rtl' : undefined,
20
- pointerEvents: isDisabled ? 'none' : undefined,
21
- // cancel mouse events when disabled
22
- position: 'relative'
20
+ position: 'relative',
21
+ font: "var(--ds-font-body, normal 400 14px/20px ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, system-ui, \"Helvetica Neue\", sans-serif)",
22
+ pointerEvents: 'all',
23
+ cursor: isDisabled ? 'not-allowed' : undefined
23
24
  });
24
25
 
25
26
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
@@ -41,11 +42,9 @@ export const SelectContainer = props => {
41
42
  // ==============================
42
43
 
43
44
  export const valueContainerCSS = ({
44
- theme: {
45
- spacing
46
- },
47
45
  isMulti,
48
46
  hasValue,
47
+ isCompact,
49
48
  selectProps: {
50
49
  controlShouldRenderValue
51
50
  }
@@ -57,7 +56,7 @@ export const valueContainerCSS = ({
57
56
  WebkitOverflowScrolling: 'touch',
58
57
  position: 'relative',
59
58
  overflow: 'hidden',
60
- padding: `${spacing.baseUnit / 2}px ${spacing.baseUnit * 2}px`
59
+ padding: `${isCompact ? 0 : "var(--ds-space-025, 2px)"} ${"var(--ds-space-075, 6px)"}`
61
60
  });
62
61
 
63
62
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
@@ -89,7 +88,8 @@ export const indicatorsContainerCSS = () => ({
89
88
  alignItems: 'center',
90
89
  alignSelf: 'stretch',
91
90
  display: 'flex',
92
- flexShrink: 0
91
+ flexShrink: 0,
92
+ paddingRight: "var(--ds-space-050, 4px)"
93
93
  });
94
94
 
95
95
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
@@ -9,32 +9,79 @@ import { getStyleProps } from '../utils';
9
9
  export const css = ({
10
10
  isDisabled,
11
11
  isFocused,
12
- theme: {
13
- colors,
14
- borderRadius,
15
- spacing
12
+ isInvalid,
13
+ isCompact,
14
+ appearance
15
+ }) => {
16
+ let borderColor = isFocused ? "var(--ds-border-focused, #388BFF)" : "var(--ds-border-input, #8590A2)";
17
+ let backgroundColor = isFocused ? "var(--ds-background-input-pressed, #FFFFFF)" : "var(--ds-background-input, #FFFFFF)";
18
+ let backgroundColorHover = isFocused ? "var(--ds-background-input-pressed, #FFFFFF)" : "var(--ds-background-input-hovered, #F7F8F9)";
19
+ let borderColorHover = isFocused ? "var(--ds-border-focused, #388BFF)" : "var(--ds-border-input, #8590A2)";
20
+ if (isDisabled) {
21
+ backgroundColor = "var(--ds-background-disabled, #091E4208)";
22
+ borderColor = "var(--ds-background-disabled, #091E4208)";
16
23
  }
17
- }) => ({
18
- label: 'control',
19
- alignItems: 'center',
20
- cursor: 'default',
21
- display: 'flex',
22
- flexWrap: 'wrap',
23
- justifyContent: 'space-between',
24
- minHeight: spacing.controlHeight,
25
- outline: '0 !important',
26
- position: 'relative',
27
- transition: 'all 100ms',
28
- backgroundColor: isDisabled ? colors.neutral5 : colors.neutral0,
29
- borderColor: isDisabled ? colors.neutral10 : isFocused ? colors.primary : colors.neutral20,
30
- borderRadius: borderRadius,
31
- borderStyle: 'solid',
32
- borderWidth: 1,
33
- boxShadow: isFocused ? `0 0 0 1px ${colors.primary}` : undefined,
34
- '&:hover': {
35
- borderColor: isFocused ? colors.primary : colors.neutral30
24
+ if (isInvalid) {
25
+ borderColor = "var(--ds-border-danger, #E2483D)";
26
+ borderColorHover = "var(--ds-border-danger, #E2483D)";
36
27
  }
37
- });
28
+ const transitionDuration = '200ms';
29
+ if (appearance === 'subtle') {
30
+ borderColor = isFocused ? "var(--ds-border-focused, #388BFF)" : 'transparent';
31
+ backgroundColor = isFocused ? "var(--ds-surface, #FFFFFF)" : 'transparent';
32
+ backgroundColorHover = isFocused ? "var(--ds-background-input-pressed, #FFFFFF)" : "var(--ds-background-input-hovered, #F7F8F9)";
33
+ }
34
+ if (appearance === 'none') {
35
+ borderColor = 'transparent';
36
+ backgroundColor = 'transparent';
37
+ backgroundColorHover = 'transparent';
38
+ borderColorHover = 'transparent';
39
+ }
40
+ return {
41
+ label: 'control',
42
+ alignItems: 'center',
43
+ cursor: 'default',
44
+ display: 'flex',
45
+ flexWrap: 'wrap',
46
+ justifyContent: 'space-between',
47
+ outline: '0 !important',
48
+ position: 'relative',
49
+ // Turn pointer events off when disabled - this makes it so hover etc don't work.
50
+ pointerEvents: isDisabled ? 'none' : undefined,
51
+ backgroundColor,
52
+ borderColor,
53
+ borderStyle: 'solid',
54
+ borderRadius: "var(--ds-border-radius-100, 3px)",
55
+ borderWidth: "var(--ds-border-width, 1px)",
56
+ boxShadow: isInvalid ? `inset 0 0 0 ${"var(--ds-border-width, 1px)"} ${borderColor}` : 'none',
57
+ '&:focus-within': {
58
+ boxShadow: `inset 0 0 0 ${"var(--ds-border-width, 1px)"} ${borderColor}`
59
+ },
60
+ minHeight: isCompact ? 32 : 40,
61
+ padding: 0,
62
+ transition: `background-color ${transitionDuration} ease-in-out,
63
+ border-color ${transitionDuration} ease-in-out`,
64
+ '::-webkit-scrollbar': {
65
+ height: 8,
66
+ width: 8
67
+ },
68
+ '::-webkit-scrollbar-corner': {
69
+ display: 'none'
70
+ },
71
+ ':hover': {
72
+ '::-webkit-scrollbar-thumb': {
73
+ // scrollbars occur only if the user passes in a custom component with overflow: scroll
74
+ backgroundColor: 'rgba(0,0,0,0.2)'
75
+ },
76
+ cursor: 'pointer',
77
+ backgroundColor: backgroundColorHover,
78
+ borderColor: borderColorHover
79
+ },
80
+ '::-webkit-scrollbar-thumb:hover': {
81
+ backgroundColor: 'rgba(0,0,0,0.4)'
82
+ }
83
+ };
84
+ };
38
85
  const Control = props => {
39
86
  const {
40
87
  children,