@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
@@ -201,7 +201,7 @@ export var menuCSS = function menuCSS(_ref2) {
201
201
  colors = _ref2$theme.colors;
202
202
  return _ref3 = {
203
203
  label: 'menu'
204
- }, _defineProperty(_ref3, alignToControl(placement), '100%'), _defineProperty(_ref3, "position", 'absolute'), _defineProperty(_ref3, "width", '100%'), _defineProperty(_ref3, "zIndex", 1), _defineProperty(_ref3, "backgroundColor", colors.neutral0), _defineProperty(_ref3, "borderRadius", borderRadius), _defineProperty(_ref3, "boxShadow", '0 0 0 1px hsla(0, 0%, 0%, 0.1), 0 4px 11px hsla(0, 0%, 0%, 0.1)'), _defineProperty(_ref3, "marginBottom", spacing.menuGutter), _defineProperty(_ref3, "marginTop", spacing.menuGutter), _ref3;
204
+ }, _defineProperty(_ref3, alignToControl(placement), '100%'), _defineProperty(_ref3, "position", 'absolute'), _defineProperty(_ref3, "width", '100%'), _defineProperty(_ref3, "zIndex", 1), _defineProperty(_ref3, "borderRadius", borderRadius), _defineProperty(_ref3, "marginBottom", spacing.menuGutter), _defineProperty(_ref3, "marginTop", spacing.menuGutter), _defineProperty(_ref3, "backgroundColor", "var(--ds-surface-overlay, white)"), _defineProperty(_ref3, "boxShadow", "var(--ds-shadow-overlay, 0 0 0 1px hsl(0deg 0% 0% / 10%), 0 4px 11px hsl(0deg 0% 0% / 10%))"), _ref3;
205
205
  };
206
206
  var PortalPlacementContext = /*#__PURE__*/createContext(null);
207
207
 
@@ -276,16 +276,15 @@ export default Menu;
276
276
  // ==============================
277
277
 
278
278
  export var menuListCSS = function menuListCSS(_ref5) {
279
- var maxHeight = _ref5.maxHeight,
280
- baseUnit = _ref5.theme.spacing.baseUnit;
279
+ var maxHeight = _ref5.maxHeight;
281
280
  return {
282
281
  maxHeight: maxHeight,
283
282
  overflowY: 'auto',
284
283
  position: 'relative',
285
284
  // required for offset[Height, Top] > keyboard scroll
286
285
  WebkitOverflowScrolling: 'touch',
287
- paddingBottom: baseUnit,
288
- paddingTop: baseUnit
286
+ paddingTop: "var(--ds-space-100, 8px)",
287
+ paddingBottom: "var(--ds-space-100, 8px)"
289
288
  };
290
289
  };
291
290
 
@@ -1,5 +1,5 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
1
  import _extends from "@babel/runtime/helpers/extends";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
  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; }
4
4
  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; }
5
5
  /**
@@ -8,57 +8,113 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
8
8
  */
9
9
 
10
10
  import { jsx } from '@emotion/react';
11
+ import { fg } from '@atlaskit/platform-feature-flags';
11
12
  import { getStyleProps } from '../utils';
12
13
  import { CrossIcon } from './indicators';
13
14
  export var multiValueCSS = function multiValueCSS(_ref) {
14
- var _ref$theme = _ref.theme,
15
+ var isDisabled = _ref.isDisabled,
16
+ isFocused = _ref.isFocused,
17
+ _ref$theme = _ref.theme,
15
18
  spacing = _ref$theme.spacing,
16
19
  borderRadius = _ref$theme.borderRadius,
17
20
  colors = _ref$theme.colors;
18
- return {
21
+ var backgroundColor;
22
+ var color;
23
+ if (isDisabled) {
24
+ // Use the basic neutral background so it is slightly separate from the
25
+ // field's background
26
+ backgroundColor = "var(--ds-background-neutral, #091E420F)";
27
+ color = "var(--ds-text-disabled, #091E424F)";
28
+ } else if (isFocused) {
29
+ backgroundColor = "var(--ds-background-selected, #E9F2FF)";
30
+ color = "var(--ds-text-selected, hsl(0, 0%, 20%))";
31
+ } else {
32
+ backgroundColor = fg('platform-component-visual-refresh') ? "var(--ds-background-neutral-subtle-hovered, #091E420F)" : "var(--ds-background-neutral, #091E420F)";
33
+ color = "var(--ds-text, hsl(0, 0%, 20%))";
34
+ }
35
+ return _objectSpread({
19
36
  label: 'multiValue',
20
37
  display: 'flex',
21
38
  minWidth: 0,
22
39
  // resolves flex/text-overflow bug
23
- backgroundColor: colors.neutral10,
24
- borderRadius: borderRadius / 2,
25
- margin: spacing.baseUnit / 2
26
- };
40
+ margin: "var(--ds-space-025, 2px)",
41
+ borderRadius: "var(--ds-border-radius-050, 2px)",
42
+ backgroundColor: backgroundColor,
43
+ boxShadow: isFocused ? "0 0 0 2px ".concat("var(--ds-surface, transparent)", ", 0 0 0 4px ", "var(--ds-border-focused, transparent)") : 'none',
44
+ maxWidth: '100%',
45
+ '@media screen and (-ms-high-contrast: active)': {
46
+ border: isFocused ? '1px solid transparent' : 'none'
47
+ },
48
+ color: color
49
+ }, fg('platform-component-visual-refresh') && {
50
+ borderRadius: "var(--ds-border-radius-100, 4px)",
51
+ // Hardcode this color for visual refresh as there is no token color yet
52
+ borderColor: '#B7B9BE',
53
+ borderWidth: "var(--ds-border-width, 1px)",
54
+ borderStyle: 'solid',
55
+ backgroundColor: "var(--ds-background-input, #FFFFFF)"
56
+ });
27
57
  };
28
58
  export var multiValueLabelCSS = function multiValueLabelCSS(_ref2) {
29
- var _ref2$theme = _ref2.theme,
30
- borderRadius = _ref2$theme.borderRadius,
31
- colors = _ref2$theme.colors,
32
- cropWithEllipsis = _ref2.cropWithEllipsis;
33
- return {
59
+ var cropWithEllipsis = _ref2.cropWithEllipsis,
60
+ isDisabled = _ref2.isDisabled;
61
+ return _objectSpread({
34
62
  overflow: 'hidden',
35
63
  textOverflow: cropWithEllipsis || cropWithEllipsis === undefined ? 'ellipsis' : undefined,
36
64
  whiteSpace: 'nowrap',
37
- borderRadius: borderRadius / 2,
38
- color: colors.neutral80,
65
+ borderRadius: "var(--ds-border-radius-050, 2px)",
39
66
  fontSize: '85%',
40
- padding: 3,
41
- paddingLeft: 6
42
- };
67
+ font: "var(--ds-font-body-UNSAFE_small, normal 400 12px/16px ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, system-ui, \"Helvetica Neue\", sans-serif)",
68
+ padding: "var(--ds-space-025, 2px)",
69
+ color: isDisabled ? "var(--ds-text-disabled, #091E424F)" : 'inherit',
70
+ paddingLeft: "var(--ds-space-075, 6px)"
71
+ }, fg('platform-component-visual-refresh') && {
72
+ font: "var(--ds-font-body, normal 400 14px/20px ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, system-ui, \"Helvetica Neue\", sans-serif)",
73
+ paddingTop: 0,
74
+ paddingBottom: 0,
75
+ paddingLeft: "var(--ds-space-050, 4px)"
76
+ });
43
77
  };
44
78
  export var multiValueRemoveCSS = function multiValueRemoveCSS(_ref3) {
45
- var _ref3$theme = _ref3.theme,
46
- spacing = _ref3$theme.spacing,
47
- borderRadius = _ref3$theme.borderRadius,
48
- colors = _ref3$theme.colors,
49
- isFocused = _ref3.isFocused;
50
- return {
79
+ var isFocused = _ref3.isFocused;
80
+ return _objectSpread({
51
81
  alignItems: 'center',
52
82
  display: 'flex',
53
- borderRadius: borderRadius / 2,
54
- backgroundColor: isFocused ? colors.dangerLight : undefined,
55
- paddingLeft: spacing.baseUnit,
56
- paddingRight: spacing.baseUnit,
83
+ backgroundColor: isFocused ? "var(--ds-UNSAFE-transparent, transparent)" : undefined,
84
+ fill: isFocused ? "var(--ds-text-selected, #000)" : "var(--ds-text, #000)",
85
+ paddingLeft: "var(--ds-space-025, 2px)",
86
+ paddingRight: "var(--ds-space-025, 2px)",
87
+ borderRadius: '0px 2px 2px 0px',
88
+ // DSP-6470 we should style like Tag once we have the :has selector
89
+ ':hover': {
90
+ backgroundColor: "var(--ds-background-danger-hovered, #FFD5D2)",
91
+ fill: "var(--ds-text-danger, #000)"
92
+ },
93
+ ':active': {
94
+ backgroundColor: "var(--ds-background-danger-pressed, #FD9891)",
95
+ fill: "var(--ds-text-danger, #000)"
96
+ }
97
+ }, fg('platform-component-visual-refresh') && {
98
+ backgroundColor: "var(--ds-background-neutral-subtle, #00000000)",
99
+ border: 'none',
100
+ alignItems: 'center',
101
+ justifyContent: 'center',
102
+ alignSelf: 'center',
103
+ appearance: 'none',
104
+ borderRadius: "var(--ds-border-radius, 4px)",
105
+ color: "var(--ds-text, #172B4D)",
106
+ padding: "var(--ds-space-025, 2px)",
107
+ marginRight: "var(--ds-space-025, 2px)",
108
+ ':focus-visible': {
109
+ outlineOffset: "var(--ds-space-negative-025, -2px)"
110
+ },
57
111
  ':hover': {
58
- backgroundColor: colors.dangerLight,
59
- color: colors.danger
112
+ backgroundColor: "var(--ds-background-neutral-subtle-hovered, #091E420F)"
113
+ },
114
+ ':active': {
115
+ backgroundColor: "var(--ds-background-neutral-subtle-pressed, #091E4224)"
60
116
  }
61
- };
117
+ });
62
118
  };
63
119
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
64
120
  export var MultiValueGeneric = function MultiValueGeneric(_ref4) {
@@ -5,28 +5,52 @@ import _extends from "@babel/runtime/helpers/extends";
5
5
  */
6
6
 
7
7
  import { jsx } from '@emotion/react';
8
+ import { fg } from '@atlaskit/platform-feature-flags';
9
+ import { isAppleDevice } from '../accessibility/helpers';
8
10
  import { getStyleProps } from '../utils';
11
+ import A11yText from './internal/a11y-text';
9
12
  export var optionCSS = function optionCSS(_ref) {
10
13
  var isDisabled = _ref.isDisabled,
11
14
  isFocused = _ref.isFocused,
12
- isSelected = _ref.isSelected,
13
- _ref$theme = _ref.theme,
14
- spacing = _ref$theme.spacing,
15
- colors = _ref$theme.colors;
15
+ isSelected = _ref.isSelected;
16
+ var color = "var(--ds-text, #172B4D)";
17
+ if (isDisabled) {
18
+ color = "var(--ds-text-disabled, #091E424F)";
19
+ } else if (isSelected) {
20
+ color = "var(--ds-text-selected, #0C66E4)";
21
+ }
22
+ var boxShadow;
23
+ var backgroundColor;
24
+ if (isDisabled) {
25
+ backgroundColor = undefined;
26
+ } else if (isSelected && isFocused) {
27
+ backgroundColor = "var(--ds-background-selected-hovered, #CCE0FF)";
28
+ } else if (isSelected) {
29
+ backgroundColor = "var(--ds-background-selected, #E9F2FF)";
30
+ } else if (isFocused) {
31
+ backgroundColor = "var(--ds-background-neutral-subtle-hovered, #091E420F)";
32
+ }
33
+ if (!isDisabled && (isFocused || isSelected)) {
34
+ boxShadow = "inset 2px 0px 0px ".concat("var(--ds-border-selected, #0C66E4)");
35
+ }
36
+ var cursor = isDisabled ? 'not-allowed' : 'default';
16
37
  return {
17
38
  label: 'option',
18
- cursor: 'default',
19
39
  display: 'block',
20
40
  fontSize: 'inherit',
21
41
  width: '100%',
22
42
  userSelect: 'none',
23
43
  WebkitTapHighlightColor: 'rgba(0, 0, 0, 0)',
24
- backgroundColor: isSelected ? colors.primary : isFocused ? colors.primary25 : 'transparent',
25
- color: isDisabled ? colors.neutral20 : isSelected ? colors.neutral0 : 'inherit',
26
- padding: "".concat(spacing.baseUnit * 2, "px ").concat(spacing.baseUnit * 3, "px"),
27
- // provide some affordance on touch devices
44
+ padding: "var(--ds-space-075, 6px)".concat(" ", "var(--ds-space-150, 12px)"),
45
+ backgroundColor: backgroundColor,
46
+ color: color,
47
+ cursor: cursor,
48
+ boxShadow: boxShadow,
28
49
  ':active': {
29
- backgroundColor: !isDisabled ? isSelected ? colors.primary : colors.primary50 : undefined
50
+ backgroundColor: !isDisabled ? isSelected ? "var(--ds-background-selected-pressed, #85B8FF)" : "var(--ds-background-neutral-subtle-pressed, #091E4224)" : undefined
51
+ },
52
+ '@media screen and (-ms-high-contrast: active)': {
53
+ borderLeft: !isDisabled && (isFocused || isSelected) ? '2px solid transparent' : ''
30
54
  }
31
55
  };
32
56
  };
@@ -37,17 +61,18 @@ var Option = function Option(props) {
37
61
  isSelected = props.isSelected,
38
62
  innerRef = props.innerRef,
39
63
  innerProps = props.innerProps;
64
+ // eslint-disable-next-line @atlaskit/platform/ensure-feature-flag-prefix
65
+ var isVoiceOver = isAppleDevice() && fg('design_system_select-a11y-improvement');
40
66
  return jsx("div", _extends({}, getStyleProps(props, 'option', {
41
67
  option: true,
42
68
  'option--is-disabled': isDisabled,
43
69
  'option--is-focused': isFocused,
44
70
  'option--is-selected': isSelected
45
71
  }), {
46
- ref: innerRef,
47
- "aria-disabled": isDisabled
72
+ ref: innerRef
48
73
  }, innerProps, {
49
74
  tabIndex: -1
50
- }), children);
75
+ }), children, isVoiceOver && (isSelected || isDisabled) && jsx(A11yText, null, "".concat(isSelected ? ',selected' : '').concat(isDisabled ? ',dimmed' : '')));
51
76
  };
52
77
 
53
78
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
@@ -7,15 +7,12 @@ import _extends from "@babel/runtime/helpers/extends";
7
7
  import { jsx } from '@emotion/react';
8
8
  import { getStyleProps } from '../utils';
9
9
  export var placeholderCSS = function placeholderCSS(_ref) {
10
- var _ref$theme = _ref.theme,
11
- spacing = _ref$theme.spacing,
12
- colors = _ref$theme.colors;
10
+ var isDisabled = _ref.isDisabled;
13
11
  return {
14
12
  label: 'placeholder',
15
13
  gridArea: '1 / 1 / 2 / 3',
16
- color: colors.neutral50,
17
- marginLeft: spacing.baseUnit / 2,
18
- marginRight: spacing.baseUnit / 2
14
+ margin: "0 ".concat("var(--ds-space-025, 2px)"),
15
+ color: isDisabled ? "var(--ds-text-disabled, #091E424F)" : "var(--ds-text-subtlest, #626F86)"
19
16
  };
20
17
  };
21
18
  var Placeholder = function Placeholder(props) {
@@ -8,9 +8,7 @@ import { jsx } from '@emotion/react';
8
8
  import { getStyleProps } from '../utils';
9
9
  export var css = function css(_ref) {
10
10
  var isDisabled = _ref.isDisabled,
11
- _ref$theme = _ref.theme,
12
- spacing = _ref$theme.spacing,
13
- colors = _ref$theme.colors;
11
+ spacing = _ref.theme.spacing;
14
12
  return {
15
13
  label: 'singleValue',
16
14
  gridArea: '1 / 1 / 2 / 3',
@@ -18,9 +16,8 @@ export var css = function css(_ref) {
18
16
  overflow: 'hidden',
19
17
  textOverflow: 'ellipsis',
20
18
  whiteSpace: 'nowrap',
21
- color: isDisabled ? colors.neutral40 : colors.neutral80,
22
- marginLeft: spacing.baseUnit / 2,
23
- marginRight: spacing.baseUnit / 2
19
+ margin: "0 ".concat("var(--ds-space-025, 2px)"),
20
+ color: isDisabled ? "var(--ds-text-disabled, #091E424F)" : "var(--ds-text, #172B4D)"
24
21
  };
25
22
  };
26
23
  var SingleValue = function SingleValue(props) {
@@ -11,6 +11,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
11
11
  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
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
+ /* eslint-disable @atlaskit/platform/ensure-feature-flag-prefix */
14
15
  import React, { Component } from 'react';
15
16
  import { fg } from '@atlaskit/platform-feature-flags';
16
17
  import { isAppleDevice, isSafari } from './accessibility/helpers';
@@ -24,7 +25,8 @@ import { defaultStyles } from './styles';
24
25
  import { defaultTheme } from './theme';
25
26
  import { classNames, cleanValue, isDocumentElement, isMobileDevice, isTouchCapable, multiValueAsValue, noop, notNullish, scrollIntoView, singleValueAsValue, valueTernary } from './utils';
26
27
  export var defaultProps = {
27
- 'aria-live': 'polite',
28
+ // aria-live is by default with the live region so we don't need it
29
+ 'aria-live': fg('design_system_select-a11y-improvement') ? undefined : 'polite',
28
30
  backspaceRemovesValue: true,
29
31
  blurInputOnSelect: isTouchCapable(),
30
32
  captureMenuScroll: !isTouchCapable(),
@@ -248,7 +250,7 @@ var Select = /*#__PURE__*/function (_Component) {
248
250
  _defineProperty(_assertThisInitialized(_this), "initialTouchY", 0);
249
251
  _defineProperty(_assertThisInitialized(_this), "openAfterFocus", false);
250
252
  _defineProperty(_assertThisInitialized(_this), "scrollToFocusedOptionOnUpdate", false);
251
- _defineProperty(_assertThisInitialized(_this), "isAppleDevice", fg('design_system_select-a11y-improvement') ? isSafari() : isAppleDevice());
253
+ _defineProperty(_assertThisInitialized(_this), "isVoiceOver", fg('design_system_select-a11y-improvement') && isAppleDevice());
252
254
  // Refs
253
255
  // ------------------------------
254
256
  _defineProperty(_assertThisInitialized(_this), "controlRef", null);
@@ -749,6 +751,7 @@ var Select = /*#__PURE__*/function (_Component) {
749
751
  prevInputValue: inputValue
750
752
  });
751
753
  _this.onMenuClose();
754
+ fg('design_system_select-a11y-improvement') && event.stopPropagation(); // keep ESC on select from dismissing parent layers
752
755
  } else if (isClearable && escapeClearsValue) {
753
756
  _this.clearValue();
754
757
  }
@@ -1152,6 +1155,27 @@ var Select = /*#__PURE__*/function (_Component) {
1152
1155
  value: function formatGroupLabel(data) {
1153
1156
  return this.props.formatGroupLabel(data);
1154
1157
  }
1158
+ }, {
1159
+ key: "calculateDescription",
1160
+ value: function calculateDescription(action) {
1161
+ var descriptionProp = this.props['aria-describedby'] || this.props['descriptionId'];
1162
+ var isMulti = this.props.isMulti;
1163
+ var selectValue = this.state.selectValue;
1164
+ var defaultDescription = selectValue.length ? this.getElementId('live-region') : this.getElementId('placeholder');
1165
+ if (selectValue.length && action !== 'initial-input-focus') {
1166
+ return;
1167
+ }
1168
+ if (isMulti && isAppleDevice() && !isSafari()) {
1169
+ // chrome only friends
1170
+ return {
1171
+ 'aria-describedby': descriptionProp ? [descriptionProp, defaultDescription, this.getElementId('multi-message')].join(' ') : [defaultDescription, this.getElementId('multi-message')].join(' ')
1172
+ };
1173
+ } else {
1174
+ return {
1175
+ 'aria-describedby': descriptionProp ? [descriptionProp, defaultDescription].join(' ') : defaultDescription
1176
+ };
1177
+ }
1178
+ }
1155
1179
  }, {
1156
1180
  key: "startListeningComposition",
1157
1181
  value:
@@ -1235,30 +1259,28 @@ var Select = /*#__PURE__*/function (_Component) {
1235
1259
  ariaSelection = _this$state4.ariaSelection;
1236
1260
  var commonProps = this.commonProps;
1237
1261
  var id = inputId || this.getElementId('input');
1238
- var description = this.props['aria-describedby'] || descriptionId;
1239
1262
 
1240
1263
  // aria attributes makes the JSX "noisy", separated for clarity
1241
1264
  var ariaAttributes = _objectSpread(_objectSpread(_objectSpread({
1242
1265
  'aria-autocomplete': 'both',
1243
1266
  'aria-errormessage': this.props['aria-errormessage'],
1244
1267
  'aria-expanded': menuIsOpen,
1268
+ // 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
1245
1269
  'aria-haspopup': 'listbox',
1246
- 'aria-describedby': description,
1270
+ 'aria-describedby': this.props['aria-describedby'] || descriptionId,
1247
1271
  'aria-invalid': this.props['aria-invalid'] || isInvalid,
1248
1272
  'aria-label': this.props['aria-label'] || label,
1249
1273
  'aria-labelledby': this.props['aria-labelledby'] || labelId,
1250
1274
  'aria-required': required || isRequired,
1251
1275
  role: 'combobox',
1252
- 'aria-activedescendant': this.state.focusedOptionId || undefined
1276
+ 'aria-activedescendant': this.state.focusedOptionId || undefined,
1277
+ // Safari needs aria-owns in order for aria-activedescendant to work properly
1278
+ 'aria-owns': isSafari() && fg('design_system_select-a11y-improvement') ? this.getElementId('listbox') : undefined
1253
1279
  }, menuIsOpen && {
1254
1280
  'aria-controls': this.getElementId('listbox')
1255
1281
  }), !isSearchable && {
1256
1282
  'aria-readonly': true
1257
- }), this.hasValue() ? (ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action) === 'initial-input-focus' && {
1258
- 'aria-describedby': description ? [description, this.getElementId('live-region')].join(' ') : this.getElementId('live-region')
1259
- } : {
1260
- 'aria-describedby': description ? [description, this.getElementId('placeholder')].join(' ') : this.getElementId('placeholder')
1261
- });
1283
+ }), this.calculateDescription(ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action));
1262
1284
  if (!isSearchable) {
1263
1285
  // use a dummy input to maintain focus/blur functionality
1264
1286
  return /*#__PURE__*/React.createElement(DummyInput, _extends({
@@ -1371,7 +1393,8 @@ var Select = /*#__PURE__*/function (_Component) {
1371
1393
  var _this$props10 = this.props,
1372
1394
  clearControlLabel = _this$props10.clearControlLabel,
1373
1395
  isDisabled = _this$props10.isDisabled,
1374
- isLoading = _this$props10.isLoading;
1396
+ isLoading = _this$props10.isLoading,
1397
+ spacing = _this$props10.spacing;
1375
1398
  var isFocused = this.state.isFocused;
1376
1399
  if (!this.isClearable() || !ClearIndicator || isDisabled || !this.hasValue() || isLoading) {
1377
1400
  return null;
@@ -1381,11 +1404,13 @@ var Select = /*#__PURE__*/function (_Component) {
1381
1404
  onTouchEnd: this.onClearIndicatorTouchEnd,
1382
1405
  'aria-hidden': 'true'
1383
1406
  };
1407
+ var isCompact = spacing === 'compact';
1384
1408
  return /*#__PURE__*/React.createElement(ClearIndicator, _extends({
1385
1409
  clearControlLabel: clearControlLabel
1386
1410
  }, commonProps, {
1387
1411
  innerProps: innerProps,
1388
- isFocused: isFocused
1412
+ isFocused: isFocused,
1413
+ isCompact: isCompact
1389
1414
  }));
1390
1415
  }
1391
1416
  }, {
@@ -1396,18 +1421,21 @@ var Select = /*#__PURE__*/function (_Component) {
1396
1421
  var commonProps = this.commonProps;
1397
1422
  var _this$props11 = this.props,
1398
1423
  isDisabled = _this$props11.isDisabled,
1399
- isLoading = _this$props11.isLoading;
1424
+ isLoading = _this$props11.isLoading,
1425
+ spacing = _this$props11.spacing;
1400
1426
  var isFocused = this.state.isFocused;
1401
1427
  if (!LoadingIndicator || !isLoading) {
1402
1428
  return null;
1403
1429
  }
1430
+ var isCompact = spacing === 'compact';
1404
1431
  var innerProps = {
1405
1432
  'aria-hidden': 'true'
1406
1433
  };
1407
1434
  return /*#__PURE__*/React.createElement(LoadingIndicator, _extends({}, commonProps, {
1408
1435
  innerProps: innerProps,
1409
1436
  isDisabled: isDisabled,
1410
- isFocused: isFocused
1437
+ isFocused: isFocused,
1438
+ isCompact: isCompact
1411
1439
  }));
1412
1440
  }
1413
1441
  }, {
@@ -1438,8 +1466,11 @@ var Select = /*#__PURE__*/function (_Component) {
1438
1466
  return null;
1439
1467
  }
1440
1468
  var commonProps = this.commonProps;
1441
- var isDisabled = this.props.isDisabled;
1469
+ var _this$props12 = this.props,
1470
+ isDisabled = _this$props12.isDisabled,
1471
+ spacing = _this$props12.spacing;
1442
1472
  var isFocused = this.state.isFocused;
1473
+ var isCompact = spacing === 'compact';
1443
1474
  var innerProps = {
1444
1475
  onMouseDown: this.onDropdownIndicatorMouseDown,
1445
1476
  onTouchEnd: this.onDropdownIndicatorTouchEnd,
@@ -1448,7 +1479,8 @@ var Select = /*#__PURE__*/function (_Component) {
1448
1479
  return /*#__PURE__*/React.createElement(DropdownIndicator, _extends({}, commonProps, {
1449
1480
  innerProps: innerProps,
1450
1481
  isDisabled: isDisabled,
1451
- isFocused: isFocused
1482
+ isFocused: isFocused,
1483
+ isCompact: isCompact
1452
1484
  }));
1453
1485
  }
1454
1486
  }, {
@@ -1466,24 +1498,24 @@ var Select = /*#__PURE__*/function (_Component) {
1466
1498
  Option = _this$getComponents7.Option;
1467
1499
  var commonProps = this.commonProps;
1468
1500
  var focusedOption = this.state.focusedOption;
1469
- var _this$props12 = this.props,
1470
- captureMenuScroll = _this$props12.captureMenuScroll,
1471
- inputValue = _this$props12.inputValue,
1472
- isLoading = _this$props12.isLoading,
1473
- loadingMessage = _this$props12.loadingMessage,
1474
- minMenuHeight = _this$props12.minMenuHeight,
1475
- maxMenuHeight = _this$props12.maxMenuHeight,
1476
- menuIsOpen = _this$props12.menuIsOpen,
1477
- menuPlacement = _this$props12.menuPlacement,
1478
- menuPosition = _this$props12.menuPosition,
1479
- menuPortalTarget = _this$props12.menuPortalTarget,
1480
- menuShouldBlockScroll = _this$props12.menuShouldBlockScroll,
1481
- menuShouldScrollIntoView = _this$props12.menuShouldScrollIntoView,
1482
- noOptionsMessage = _this$props12.noOptionsMessage,
1483
- onMenuScrollToTop = _this$props12.onMenuScrollToTop,
1484
- onMenuScrollToBottom = _this$props12.onMenuScrollToBottom,
1485
- labelId = _this$props12.labelId,
1486
- label = _this$props12.label;
1501
+ var _this$props13 = this.props,
1502
+ captureMenuScroll = _this$props13.captureMenuScroll,
1503
+ inputValue = _this$props13.inputValue,
1504
+ isLoading = _this$props13.isLoading,
1505
+ loadingMessage = _this$props13.loadingMessage,
1506
+ minMenuHeight = _this$props13.minMenuHeight,
1507
+ maxMenuHeight = _this$props13.maxMenuHeight,
1508
+ menuIsOpen = _this$props13.menuIsOpen,
1509
+ menuPlacement = _this$props13.menuPlacement,
1510
+ menuPosition = _this$props13.menuPosition,
1511
+ menuPortalTarget = _this$props13.menuPortalTarget,
1512
+ menuShouldBlockScroll = _this$props13.menuShouldBlockScroll,
1513
+ menuShouldScrollIntoView = _this$props13.menuShouldScrollIntoView,
1514
+ noOptionsMessage = _this$props13.noOptionsMessage,
1515
+ onMenuScrollToTop = _this$props13.onMenuScrollToTop,
1516
+ onMenuScrollToBottom = _this$props13.onMenuScrollToBottom,
1517
+ labelId = _this$props13.labelId,
1518
+ label = _this$props13.label;
1487
1519
  if (!menuIsOpen) {
1488
1520
  return null;
1489
1521
  }
@@ -1510,7 +1542,10 @@ var Select = /*#__PURE__*/function (_Component) {
1510
1542
  onMouseMove: onHover,
1511
1543
  onMouseOver: onHover,
1512
1544
  role: 'option',
1513
- 'aria-selected': !commonProps.isMulti && fg('design_system_select-a11y-improvement') ? isSelected || undefined : isSelected,
1545
+ // We don't want aria-selected on Apple devices or if it's false. It does nasty things.
1546
+ 'aria-selected': (!commonProps.isMulti || _this4.isVoiceOver || !isSelected) && fg('design_system_select-a11y-improvement') ? undefined : isSelected,
1547
+ // We don't want aria-disabled on Apple devices or if it's false. It's just noisy.
1548
+ 'aria-disabled': (isAppleDevice() || !isDisabled) && fg('design_system_select-a11y-improvement') ? undefined : isDisabled,
1514
1549
  'aria-describedby': fg('design_system_select-a11y-improvement') ? headingId : undefined
1515
1550
  };
1516
1551
  return /*#__PURE__*/React.createElement(Option, _extends({}, commonProps, {
@@ -1604,12 +1639,11 @@ var Select = /*#__PURE__*/function (_Component) {
1604
1639
  },
1605
1640
  innerProps: _objectSpread({
1606
1641
  role: 'listbox',
1607
- // don't add aria-multiselectable when ff is on and the value is false
1608
- 'aria-multiselectable': fg('design_system_select-a11y-improvement') ? commonProps.isMulti || undefined : commonProps.isMulti,
1642
+ 'aria-multiselectable': (_this4.isVoiceOver || !commonProps.isMulti) && fg('design_system_select-a11y-improvement') ? undefined : commonProps.isMulti,
1609
1643
  id: _this4.getElementId('listbox')
1610
1644
  }, fg('design_system_select-a11y-improvement') && {
1611
1645
  'aria-label': label,
1612
- 'aria-labelledby': labelId
1646
+ 'aria-labelledby': "".concat(labelId || _this4.getElementId('input'), " ").concat(commonProps.isMulti && isSafari() ? _this4.getElementId('multi-message') : '')
1613
1647
  }),
1614
1648
  isLoading: isLoading,
1615
1649
  maxHeight: maxHeight,
@@ -1632,12 +1666,12 @@ var Select = /*#__PURE__*/function (_Component) {
1632
1666
  key: "renderFormField",
1633
1667
  value: function renderFormField() {
1634
1668
  var _this5 = this;
1635
- var _this$props13 = this.props,
1636
- delimiter = _this$props13.delimiter,
1637
- isDisabled = _this$props13.isDisabled,
1638
- isMulti = _this$props13.isMulti,
1639
- required = _this$props13.required,
1640
- name = _this$props13.name;
1669
+ var _this$props14 = this.props,
1670
+ delimiter = _this$props14.delimiter,
1671
+ isDisabled = _this$props14.isDisabled,
1672
+ isMulti = _this$props14.isMulti,
1673
+ required = _this$props14.required,
1674
+ name = _this$props14.name;
1641
1675
  var selectValue = this.state.selectValue;
1642
1676
  if (required && !this.hasValue() && !isDisabled) {
1643
1677
  return /*#__PURE__*/React.createElement(RequiredInput, {
@@ -1701,9 +1735,17 @@ var Select = /*#__PURE__*/function (_Component) {
1701
1735
  isFocused: isFocused,
1702
1736
  selectValue: selectValue,
1703
1737
  focusableOptions: focusableOptions,
1704
- isAppleDevice: this.isAppleDevice
1738
+ isAppleDevice: this.isVoiceOver
1705
1739
  }));
1706
1740
  }
1741
+ }, {
1742
+ key: "renderMultiselectMessage",
1743
+ value: function renderMultiselectMessage() {
1744
+ return /*#__PURE__*/React.createElement("span", {
1745
+ id: this.getElementId('multi-message'),
1746
+ hidden: true
1747
+ }, ", multiple selections available,");
1748
+ }
1707
1749
  }, {
1708
1750
  key: "render",
1709
1751
  value: function render() {
@@ -1712,13 +1754,19 @@ var Select = /*#__PURE__*/function (_Component) {
1712
1754
  IndicatorsContainer = _this$getComponents8.IndicatorsContainer,
1713
1755
  SelectContainer = _this$getComponents8.SelectContainer,
1714
1756
  ValueContainer = _this$getComponents8.ValueContainer;
1715
- var _this$props14 = this.props,
1716
- className = _this$props14.className,
1717
- id = _this$props14.id,
1718
- isDisabled = _this$props14.isDisabled,
1719
- menuIsOpen = _this$props14.menuIsOpen;
1757
+ var _this$props15 = this.props,
1758
+ className = _this$props15.className,
1759
+ id = _this$props15.id,
1760
+ isDisabled = _this$props15.isDisabled,
1761
+ menuIsOpen = _this$props15.menuIsOpen,
1762
+ isInvalid = _this$props15.isInvalid,
1763
+ _this$props15$appeara = _this$props15.appearance,
1764
+ appearance = _this$props15$appeara === void 0 ? 'default' : _this$props15$appeara,
1765
+ _this$props15$spacing = _this$props15.spacing,
1766
+ spacing = _this$props15$spacing === void 0 ? 'default' : _this$props15$spacing;
1720
1767
  var isFocused = this.state.isFocused;
1721
1768
  var commonProps = this.commonProps = this.getCommonProps();
1769
+ var isCompact = spacing === 'compact';
1722
1770
  return /*#__PURE__*/React.createElement(SelectContainer, _extends({}, commonProps, {
1723
1771
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
1724
1772
  className: className,
@@ -1728,17 +1776,21 @@ var Select = /*#__PURE__*/function (_Component) {
1728
1776
  },
1729
1777
  isDisabled: isDisabled,
1730
1778
  isFocused: isFocused
1731
- }), this.renderLiveRegion(), /*#__PURE__*/React.createElement(Control, _extends({}, commonProps, {
1779
+ }), this.renderLiveRegion(), commonProps.isMulti && this.isVoiceOver && this.renderMultiselectMessage(), /*#__PURE__*/React.createElement(Control, _extends({}, commonProps, {
1732
1780
  innerRef: this.getControlRef,
1733
1781
  innerProps: {
1734
1782
  onMouseDown: this.onControlMouseDown,
1735
1783
  onTouchEnd: this.onControlTouchEnd
1736
1784
  },
1785
+ appearance: appearance,
1786
+ isInvalid: isInvalid,
1737
1787
  isDisabled: isDisabled,
1738
1788
  isFocused: isFocused,
1739
- menuIsOpen: menuIsOpen
1789
+ menuIsOpen: menuIsOpen,
1790
+ isCompact: isCompact
1740
1791
  }), /*#__PURE__*/React.createElement(ValueContainer, _extends({}, commonProps, {
1741
- isDisabled: isDisabled
1792
+ isDisabled: isDisabled,
1793
+ isCompact: isCompact
1742
1794
  }), this.renderPlaceholderOrValue(), this.renderInput()), /*#__PURE__*/React.createElement(IndicatorsContainer, _extends({}, commonProps, {
1743
1795
  isDisabled: isDisabled
1744
1796
  }), this.renderClearIndicator(), this.renderLoadingIndicator(), this.renderIndicatorSeparator(), this.renderDropdownIndicator())), this.renderMenu(), this.renderFormField());
@@ -32,8 +32,12 @@ export interface ValueContainerProps<Option = unknown, IsMulti extends boolean =
32
32
  */
33
33
  children: ReactNode;
34
34
  isDisabled: boolean;
35
+ /**
36
+ * Whether the select is compact.
37
+ */
38
+ isCompact?: boolean;
35
39
  }
36
- export declare const valueContainerCSS: <Option, IsMulti extends boolean, Group extends GroupBase<Option>>({ theme: { spacing }, isMulti, hasValue, selectProps: { controlShouldRenderValue }, }: ValueContainerProps<Option, IsMulti, Group>) => CSSObjectWithLabel;
40
+ export declare const valueContainerCSS: <Option, IsMulti extends boolean, Group extends GroupBase<Option>>({ isMulti, hasValue, isCompact, selectProps: { controlShouldRenderValue }, }: ValueContainerProps<Option, IsMulti, Group>) => CSSObjectWithLabel;
37
41
  export declare const ValueContainer: <Option, IsMulti extends boolean, Group extends GroupBase<Option>>(props: ValueContainerProps<Option, IsMulti, Group>) => jsx.JSX.Element;
38
42
  export interface IndicatorsContainerProps<Option = unknown, IsMulti extends boolean = boolean, Group extends GroupBase<Option> = GroupBase<Option>> extends CommonPropsAndClassName<Option, IsMulti, Group> {
39
43
  isDisabled: boolean;