@atlaskit/select 15.2.13 → 15.3.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @atlaskit/select
2
2
 
3
+ ## 15.3.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`8a5bdb3c844`](https://bitbucket.org/atlassian/atlassian-frontend/commits/8a5bdb3c844) - Upgrading internal dependency (bind-event-listener) for improved internal types
8
+
9
+ ## 15.3.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [`8f6f225ac11`](https://bitbucket.org/atlassian/atlassian-frontend/commits/8f6f225ac11) - Updated prop types for Popup Select
14
+ - [`e4b612d1c48`](https://bitbucket.org/atlassian/atlassian-frontend/commits/e4b612d1c48) - Internal migration to bind-event-listener for safer DOM Event cleanup
15
+
16
+ ## 15.3.0
17
+
18
+ ### Minor Changes
19
+
20
+ - [`145c9cea461`](https://bitbucket.org/atlassian/atlassian-frontend/commits/145c9cea461) - [ux] Added 2 new props for controlling the open state of PopupSelect:
21
+
22
+ - `isOpen` controls whether the popup is open (controlled)
23
+ - `defaultIsOpen` controls whether the popup is initially open on mount (uncontrolled)
24
+
25
+ ### Patch Changes
26
+
27
+ - [`db58fa26cbf`](https://bitbucket.org/atlassian/atlassian-frontend/commits/db58fa26cbf) - [ux] Updated input tokens within `@atlaskit/select`.
28
+ - [`4624991be21`](https://bitbucket.org/atlassian/atlassian-frontend/commits/4624991be21) - [ux] Fixes a regression affecting MacOS Safari. The cursor incorrectly displayed as 'text' rather than 'default' when the pointer was over a select option.
29
+ - [`e7438659c2e`](https://bitbucket.org/atlassian/atlassian-frontend/commits/e7438659c2e) - Updated dependency '@types/react-select' to fix type error
30
+
3
31
  ## 15.2.13
4
32
 
5
33
  ### Patch Changes
@@ -49,6 +49,8 @@ var _components = require("./components");
49
49
 
50
50
  var _styles = _interopRequireDefault(require("../styles"));
51
51
 
52
+ var _bindEventListener = require("bind-event-listener");
53
+
52
54
  var _excluded = ["footer", "maxMenuWidth", "minMenuWidth", "target"];
53
55
 
54
56
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -103,6 +105,8 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
103
105
  var _super = _createSuper(PopupSelect);
104
106
 
105
107
  function PopupSelect() {
108
+ var _this$defaultOpenStat;
109
+
106
110
  var _this;
107
111
 
108
112
  (0, _classCallCheck2.default)(this, PopupSelect);
@@ -116,6 +120,8 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
116
120
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "menuRef", null);
117
121
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "selectRef", null);
118
122
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "targetRef", null);
123
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "unbindWindowClick", null);
124
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "unbindWindowKeydown", null);
119
125
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "defaultStyles", (0, _reactSelect.mergeStyles)((0, _styles.default)(_this.props.validationState, _this.props.spacing === 'compact'), {
120
126
  groupHeading: function groupHeading(provided) {
121
127
  return _objectSpread(_objectSpread({}, provided), {}, {
@@ -123,8 +129,10 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
123
129
  });
124
130
  }
125
131
  }));
132
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isOpenControlled", _this.props.isOpen !== undefined);
133
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "defaultOpenState", _this.isOpenControlled ? _this.props.isOpen : _this.props.defaultIsOpen);
126
134
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", {
127
- isOpen: false,
135
+ isOpen: (_this$defaultOpenStat = _this.defaultOpenState) !== null && _this$defaultOpenStat !== void 0 ? _this$defaultOpenStat : false,
128
136
  mergedComponents: _components.defaultComponents,
129
137
  mergedPopperProps: defaultPopperProps
130
138
  });
@@ -180,9 +188,14 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
180
188
  onChange(value, actionMeta);
181
189
  }
182
190
  });
183
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "open", function () {
191
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "open", function (options) {
184
192
  var onOpen = _this.props.onOpen;
185
193
 
194
+ if (!(options !== null && options !== void 0 && options.controlOverride) && _this.isOpenControlled) {
195
+ // Prevent popup opening if it's open state is already being controlled
196
+ return;
197
+ }
198
+
186
199
  if (onOpen) {
187
200
  onOpen();
188
201
  }
@@ -200,7 +213,13 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
200
213
  return;
201
214
  }
202
215
 
203
- window.addEventListener('keydown', _this.handleKeyDown, true);
216
+ _this.unbindWindowKeydown = (0, _bindEventListener.bind)(window, {
217
+ type: 'keydown',
218
+ listener: _this.handleKeyDown,
219
+ options: {
220
+ capture: true
221
+ }
222
+ });
204
223
  });
205
224
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "initialiseFocusTrap", function () {
206
225
  if (!_this.menuRef) {
@@ -219,9 +238,16 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
219
238
  return _this.focusTrap.activate();
220
239
  }, 1);
221
240
  });
222
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "close", function () {
241
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "close", function (options) {
242
+ var _this$unbindWindowKey, _this2;
243
+
223
244
  var onClose = _this.props.onClose;
224
245
 
246
+ if (!(options !== null && options !== void 0 && options.controlOverride) && _this.isOpenControlled) {
247
+ // Prevent popup closing if it's open state is already being controlled
248
+ return;
249
+ }
250
+
225
251
  if (onClose) {
226
252
  onClose();
227
253
  }
@@ -242,7 +268,8 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
242
268
  return;
243
269
  }
244
270
 
245
- window.removeEventListener('keydown', _this.handleKeyDown, true);
271
+ (_this$unbindWindowKey = (_this2 = _this).unbindWindowKeydown) === null || _this$unbindWindowKey === void 0 ? void 0 : _this$unbindWindowKey.call(_this2);
272
+ _this.unbindWindowKeydown = null;
246
273
  });
247
274
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "resolveTargetRef", function (popperRef) {
248
275
  return function (ref) {
@@ -370,24 +397,51 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
370
397
  return;
371
398
  }
372
399
 
373
- window.addEventListener('click', this.handleClick, true);
400
+ this.unbindWindowClick = (0, _bindEventListener.bind)(window, {
401
+ type: 'click',
402
+ listener: this.handleClick,
403
+ options: {
404
+ capture: true
405
+ }
406
+ });
374
407
  }
375
408
  }, {
376
409
  key: "componentWillUnmount",
377
410
  value: function componentWillUnmount() {
411
+ var _this$unbindWindowCli, _this$unbindWindowKey2;
412
+
378
413
  if (typeof window === 'undefined') {
379
414
  return;
380
415
  }
381
416
 
382
- window.removeEventListener('click', this.handleClick, true);
383
- window.removeEventListener('keydown', this.handleKeyDown, true);
417
+ (_this$unbindWindowCli = this.unbindWindowClick) === null || _this$unbindWindowCli === void 0 ? void 0 : _this$unbindWindowCli.call(this);
418
+ this.unbindWindowClick = null;
419
+ (_this$unbindWindowKey2 = this.unbindWindowKeydown) === null || _this$unbindWindowKey2 === void 0 ? void 0 : _this$unbindWindowKey2.call(this);
420
+ this.unbindWindowKeydown = null;
421
+ }
422
+ }, {
423
+ key: "componentDidUpdate",
424
+ value: function componentDidUpdate(prevProps) {
425
+ var isOpen = this.props.isOpen;
426
+
427
+ if (prevProps.isOpen !== isOpen) {
428
+ if (isOpen === true) {
429
+ this.open({
430
+ controlOverride: true
431
+ });
432
+ } else if (isOpen === false) {
433
+ this.close({
434
+ controlOverride: true
435
+ });
436
+ }
437
+ }
384
438
  } // Event Handlers
385
439
  // ==============================
386
440
 
387
441
  }, {
388
442
  key: "render",
389
443
  value: function render() {
390
- var _this2 = this;
444
+ var _this3 = this;
391
445
 
392
446
  var target = this.props.target;
393
447
  var isOpen = this.state.isOpen;
@@ -395,10 +449,10 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
395
449
  var ref = _ref3.ref;
396
450
  return target && target({
397
451
  isOpen: isOpen,
398
- ref: _this2.resolveTargetRef(ref),
452
+ ref: _this3.resolveTargetRef(ref),
399
453
  'aria-haspopup': 'true',
400
454
  'aria-expanded': isOpen,
401
- 'aria-controls': isOpen ? _this2.popperWrapperId : undefined
455
+ 'aria-controls': isOpen ? _this3.popperWrapperId : undefined
402
456
  });
403
457
  }), this.renderSelect());
404
458
  }
@@ -14,7 +14,7 @@ var _analyticsNext = require("@atlaskit/analytics-next");
14
14
  var _createSelect = _interopRequireDefault(require("./createSelect"));
15
15
 
16
16
  var packageName = "@atlaskit/select";
17
- var packageVersion = "15.2.13";
17
+ var packageVersion = "15.3.2";
18
18
  var SelectWithoutAnalytics = (0, _createSelect.default)(_reactSelect.default);
19
19
  exports.SelectWithoutAnalytics = SelectWithoutAnalytics;
20
20
  var createAndFireEventOnAtlaskit = (0, _analyticsNext.createAndFireEvent)('atlaskit');
@@ -30,7 +30,7 @@ function baseStyles(validationState, isCompact) {
30
30
  // react-select disables pointer events when isDisabled is true.
31
31
  // We override this and make the inner container turn it off instead.
32
32
  pointerEvents: 'all',
33
- cursor: isDisabled ? 'not-allowed' : undefined
33
+ cursor: isDisabled ? 'not-allowed' : css.cursor
34
34
  });
35
35
  },
36
36
  input: function input(css) {
@@ -176,14 +176,14 @@ function baseStyles(validationState, isCompact) {
176
176
  } else if (isSelected) {
177
177
  backgroundColor = "var(--ds-background-selected, ".concat(_colors.B50, ")");
178
178
  } else if (isFocused) {
179
- backgroundColor = "var(--ds-background-neutral-subtle-hovered, ".concat(_colors.N20, ")");
179
+ backgroundColor = "var(--ds-background-input-pressed, ".concat(_colors.N20, ")");
180
180
  }
181
181
 
182
182
  if (!isDisabled && (isFocused || isSelected)) {
183
183
  boxShadow = "inset 2px 0px 0px ".concat("var(--ds-border-selected, ".concat(_colors.B400, ")"));
184
184
  }
185
185
 
186
- var cursor = isDisabled ? 'not-allowed' : undefined;
186
+ var cursor = isDisabled ? 'not-allowed' : css.cursor;
187
187
  return _objectSpread(_objectSpread({}, css), {}, {
188
188
  padding: '6px 12px',
189
189
  backgroundColor: backgroundColor,
@@ -229,7 +229,7 @@ function baseStyles(validationState, isCompact) {
229
229
  return _objectSpread(_objectSpread({}, css), {}, {
230
230
  borderRadius: '2px',
231
231
  backgroundColor: isFocused ? "var(--ds-background-selected, ".concat(_colors.N40, ")") : "var(--ds-background-neutral-subtle-hovered, ".concat(_colors.N40, ")"),
232
- boxShadow: isFocused ? "0 0 0 2px ".concat("var(--ds-surface, transparent)", ", 0 0 0 4px ").concat("var(--ds-border-focused, transparent)") : 'none',
232
+ boxShadow: isFocused ? "0 0 0 2px ".concat("var(--ds-surface, transparent)", ", 0 0 0 4px ", "var(--ds-border-focused, transparent)") : 'none',
233
233
  maxWidth: '100%',
234
234
  '@media screen and (-ms-high-contrast: active)': {
235
235
  border: isFocused ? '1px solid transparent' : 'none'
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/select",
3
- "version": "15.2.13",
3
+ "version": "15.3.2",
4
4
  "sideEffects": false
5
5
  }
@@ -11,6 +11,7 @@ import shallowEqualObjects from 'shallow-equal/objects';
11
11
  import { N80 } from '@atlaskit/theme/colors';
12
12
  import { MenuDialog, DummyControl, defaultComponents } from './components';
13
13
  import baseStyles from '../styles';
14
+ import { bind } from 'bind-event-listener';
14
15
 
15
16
  /** Are we rendering on the client or server? */
16
17
  const canUseDOM = () => Boolean(typeof window !== 'undefined' && window.document && window.document.createElement); // ==============================
@@ -44,6 +45,8 @@ const isEmpty = obj => Object.keys(obj).length === 0;
44
45
 
45
46
  export default class PopupSelect extends PureComponent {
46
47
  constructor(...args) {
48
+ var _this$defaultOpenStat;
49
+
47
50
  super(...args);
48
51
 
49
52
  _defineProperty(this, "focusTrap", null);
@@ -54,14 +57,22 @@ export default class PopupSelect extends PureComponent {
54
57
 
55
58
  _defineProperty(this, "targetRef", null);
56
59
 
60
+ _defineProperty(this, "unbindWindowClick", null);
61
+
62
+ _defineProperty(this, "unbindWindowKeydown", null);
63
+
57
64
  _defineProperty(this, "defaultStyles", mergeStyles(baseStyles(this.props.validationState, this.props.spacing === 'compact'), {
58
65
  groupHeading: provided => ({ ...provided,
59
66
  color: `var(--ds-text-subtlest, ${N80})`
60
67
  })
61
68
  }));
62
69
 
70
+ _defineProperty(this, "isOpenControlled", this.props.isOpen !== undefined);
71
+
72
+ _defineProperty(this, "defaultOpenState", this.isOpenControlled ? this.props.isOpen : this.props.defaultIsOpen);
73
+
63
74
  _defineProperty(this, "state", {
64
- isOpen: false,
75
+ isOpen: (_this$defaultOpenStat = this.defaultOpenState) !== null && _this$defaultOpenStat !== void 0 ? _this$defaultOpenStat : false,
65
76
  mergedComponents: defaultComponents,
66
77
  mergedPopperProps: defaultPopperProps
67
78
  });
@@ -125,11 +136,16 @@ export default class PopupSelect extends PureComponent {
125
136
  }
126
137
  });
127
138
 
128
- _defineProperty(this, "open", () => {
139
+ _defineProperty(this, "open", options => {
129
140
  const {
130
141
  onOpen
131
142
  } = this.props;
132
143
 
144
+ if (!(options !== null && options !== void 0 && options.controlOverride) && this.isOpenControlled) {
145
+ // Prevent popup opening if it's open state is already being controlled
146
+ return;
147
+ }
148
+
133
149
  if (onOpen) {
134
150
  onOpen();
135
151
  }
@@ -146,7 +162,13 @@ export default class PopupSelect extends PureComponent {
146
162
  return;
147
163
  }
148
164
 
149
- window.addEventListener('keydown', this.handleKeyDown, true);
165
+ this.unbindWindowKeydown = bind(window, {
166
+ type: 'keydown',
167
+ listener: this.handleKeyDown,
168
+ options: {
169
+ capture: true
170
+ }
171
+ });
150
172
  });
151
173
 
152
174
  _defineProperty(this, "initialiseFocusTrap", () => {
@@ -165,11 +187,18 @@ export default class PopupSelect extends PureComponent {
165
187
  setTimeout(() => this.focusTrap.activate(), 1);
166
188
  });
167
189
 
168
- _defineProperty(this, "close", () => {
190
+ _defineProperty(this, "close", options => {
191
+ var _this$unbindWindowKey;
192
+
169
193
  const {
170
194
  onClose
171
195
  } = this.props;
172
196
 
197
+ if (!(options !== null && options !== void 0 && options.controlOverride) && this.isOpenControlled) {
198
+ // Prevent popup closing if it's open state is already being controlled
199
+ return;
200
+ }
201
+
173
202
  if (onClose) {
174
203
  onClose();
175
204
  }
@@ -190,7 +219,8 @@ export default class PopupSelect extends PureComponent {
190
219
  return;
191
220
  }
192
221
 
193
- window.removeEventListener('keydown', this.handleKeyDown, true);
222
+ (_this$unbindWindowKey = this.unbindWindowKeydown) === null || _this$unbindWindowKey === void 0 ? void 0 : _this$unbindWindowKey.call(this);
223
+ this.unbindWindowKeydown = null;
194
224
  });
195
225
 
196
226
  _defineProperty(this, "resolveTargetRef", popperRef => ref => {
@@ -351,16 +381,44 @@ export default class PopupSelect extends PureComponent {
351
381
  return;
352
382
  }
353
383
 
354
- window.addEventListener('click', this.handleClick, true);
384
+ this.unbindWindowClick = bind(window, {
385
+ type: 'click',
386
+ listener: this.handleClick,
387
+ options: {
388
+ capture: true
389
+ }
390
+ });
355
391
  }
356
392
 
357
393
  componentWillUnmount() {
394
+ var _this$unbindWindowCli, _this$unbindWindowKey2;
395
+
358
396
  if (typeof window === 'undefined') {
359
397
  return;
360
398
  }
361
399
 
362
- window.removeEventListener('click', this.handleClick, true);
363
- window.removeEventListener('keydown', this.handleKeyDown, true);
400
+ (_this$unbindWindowCli = this.unbindWindowClick) === null || _this$unbindWindowCli === void 0 ? void 0 : _this$unbindWindowCli.call(this);
401
+ this.unbindWindowClick = null;
402
+ (_this$unbindWindowKey2 = this.unbindWindowKeydown) === null || _this$unbindWindowKey2 === void 0 ? void 0 : _this$unbindWindowKey2.call(this);
403
+ this.unbindWindowKeydown = null;
404
+ }
405
+
406
+ componentDidUpdate(prevProps) {
407
+ const {
408
+ isOpen
409
+ } = this.props;
410
+
411
+ if (prevProps.isOpen !== isOpen) {
412
+ if (isOpen === true) {
413
+ this.open({
414
+ controlOverride: true
415
+ });
416
+ } else if (isOpen === false) {
417
+ this.close({
418
+ controlOverride: true
419
+ });
420
+ }
421
+ }
364
422
  } // Event Handlers
365
423
  // ==============================
366
424
 
@@ -2,7 +2,7 @@ import Select from 'react-select';
2
2
  import { withAnalyticsEvents, withAnalyticsContext, createAndFireEvent } from '@atlaskit/analytics-next';
3
3
  import createSelect from './createSelect';
4
4
  const packageName = "@atlaskit/select";
5
- const packageVersion = "15.2.13";
5
+ const packageVersion = "15.3.2";
6
6
  export const SelectWithoutAnalytics = createSelect(Select);
7
7
  const createAndFireEventOnAtlaskit = createAndFireEvent('atlaskit');
8
8
  export default withAnalyticsContext({
@@ -12,7 +12,7 @@ export default function baseStyles(validationState, isCompact) {
12
12
  // react-select disables pointer events when isDisabled is true.
13
13
  // We override this and make the inner container turn it off instead.
14
14
  pointerEvents: 'all',
15
- cursor: isDisabled ? 'not-allowed' : undefined
15
+ cursor: isDisabled ? 'not-allowed' : css.cursor
16
16
  }),
17
17
  input: css => ({ ...css,
18
18
  color: "var(--ds-text, hsl(0, 0%, 20%))"
@@ -151,14 +151,14 @@ export default function baseStyles(validationState, isCompact) {
151
151
  } else if (isSelected) {
152
152
  backgroundColor = `var(--ds-background-selected, ${B50})`;
153
153
  } else if (isFocused) {
154
- backgroundColor = `var(--ds-background-neutral-subtle-hovered, ${N20})`;
154
+ backgroundColor = `var(--ds-background-input-pressed, ${N20})`;
155
155
  }
156
156
 
157
157
  if (!isDisabled && (isFocused || isSelected)) {
158
158
  boxShadow = `inset 2px 0px 0px ${`var(--ds-border-selected, ${B400})`}`;
159
159
  }
160
160
 
161
- const cursor = isDisabled ? 'not-allowed' : undefined;
161
+ const cursor = isDisabled ? 'not-allowed' : css.cursor;
162
162
  return { ...css,
163
163
  padding: '6px 12px',
164
164
  backgroundColor,
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/select",
3
- "version": "15.2.13",
3
+ "version": "15.3.2",
4
4
  "sideEffects": false
5
5
  }
@@ -28,6 +28,7 @@ import shallowEqualObjects from 'shallow-equal/objects';
28
28
  import { N80 } from '@atlaskit/theme/colors';
29
29
  import { MenuDialog, DummyControl, defaultComponents } from './components';
30
30
  import baseStyles from '../styles';
31
+ import { bind } from 'bind-event-listener';
31
32
 
32
33
  /** Are we rendering on the client or server? */
33
34
  var canUseDOM = function canUseDOM() {
@@ -69,6 +70,8 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
69
70
  var _super = _createSuper(PopupSelect);
70
71
 
71
72
  function PopupSelect() {
73
+ var _this$defaultOpenStat;
74
+
72
75
  var _this;
73
76
 
74
77
  _classCallCheck(this, PopupSelect);
@@ -87,6 +90,10 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
87
90
 
88
91
  _defineProperty(_assertThisInitialized(_this), "targetRef", null);
89
92
 
93
+ _defineProperty(_assertThisInitialized(_this), "unbindWindowClick", null);
94
+
95
+ _defineProperty(_assertThisInitialized(_this), "unbindWindowKeydown", null);
96
+
90
97
  _defineProperty(_assertThisInitialized(_this), "defaultStyles", mergeStyles(baseStyles(_this.props.validationState, _this.props.spacing === 'compact'), {
91
98
  groupHeading: function groupHeading(provided) {
92
99
  return _objectSpread(_objectSpread({}, provided), {}, {
@@ -95,8 +102,12 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
95
102
  }
96
103
  }));
97
104
 
105
+ _defineProperty(_assertThisInitialized(_this), "isOpenControlled", _this.props.isOpen !== undefined);
106
+
107
+ _defineProperty(_assertThisInitialized(_this), "defaultOpenState", _this.isOpenControlled ? _this.props.isOpen : _this.props.defaultIsOpen);
108
+
98
109
  _defineProperty(_assertThisInitialized(_this), "state", {
99
- isOpen: false,
110
+ isOpen: (_this$defaultOpenStat = _this.defaultOpenState) !== null && _this$defaultOpenStat !== void 0 ? _this$defaultOpenStat : false,
100
111
  mergedComponents: defaultComponents,
101
112
  mergedPopperProps: defaultPopperProps
102
113
  });
@@ -157,9 +168,14 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
157
168
  }
158
169
  });
159
170
 
160
- _defineProperty(_assertThisInitialized(_this), "open", function () {
171
+ _defineProperty(_assertThisInitialized(_this), "open", function (options) {
161
172
  var onOpen = _this.props.onOpen;
162
173
 
174
+ if (!(options !== null && options !== void 0 && options.controlOverride) && _this.isOpenControlled) {
175
+ // Prevent popup opening if it's open state is already being controlled
176
+ return;
177
+ }
178
+
163
179
  if (onOpen) {
164
180
  onOpen();
165
181
  }
@@ -177,7 +193,13 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
177
193
  return;
178
194
  }
179
195
 
180
- window.addEventListener('keydown', _this.handleKeyDown, true);
196
+ _this.unbindWindowKeydown = bind(window, {
197
+ type: 'keydown',
198
+ listener: _this.handleKeyDown,
199
+ options: {
200
+ capture: true
201
+ }
202
+ });
181
203
  });
182
204
 
183
205
  _defineProperty(_assertThisInitialized(_this), "initialiseFocusTrap", function () {
@@ -198,9 +220,16 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
198
220
  }, 1);
199
221
  });
200
222
 
201
- _defineProperty(_assertThisInitialized(_this), "close", function () {
223
+ _defineProperty(_assertThisInitialized(_this), "close", function (options) {
224
+ var _this$unbindWindowKey, _this2;
225
+
202
226
  var onClose = _this.props.onClose;
203
227
 
228
+ if (!(options !== null && options !== void 0 && options.controlOverride) && _this.isOpenControlled) {
229
+ // Prevent popup closing if it's open state is already being controlled
230
+ return;
231
+ }
232
+
204
233
  if (onClose) {
205
234
  onClose();
206
235
  }
@@ -221,7 +250,8 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
221
250
  return;
222
251
  }
223
252
 
224
- window.removeEventListener('keydown', _this.handleKeyDown, true);
253
+ (_this$unbindWindowKey = (_this2 = _this).unbindWindowKeydown) === null || _this$unbindWindowKey === void 0 ? void 0 : _this$unbindWindowKey.call(_this2);
254
+ _this.unbindWindowKeydown = null;
225
255
  });
226
256
 
227
257
  _defineProperty(_assertThisInitialized(_this), "resolveTargetRef", function (popperRef) {
@@ -357,24 +387,51 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
357
387
  return;
358
388
  }
359
389
 
360
- window.addEventListener('click', this.handleClick, true);
390
+ this.unbindWindowClick = bind(window, {
391
+ type: 'click',
392
+ listener: this.handleClick,
393
+ options: {
394
+ capture: true
395
+ }
396
+ });
361
397
  }
362
398
  }, {
363
399
  key: "componentWillUnmount",
364
400
  value: function componentWillUnmount() {
401
+ var _this$unbindWindowCli, _this$unbindWindowKey2;
402
+
365
403
  if (typeof window === 'undefined') {
366
404
  return;
367
405
  }
368
406
 
369
- window.removeEventListener('click', this.handleClick, true);
370
- window.removeEventListener('keydown', this.handleKeyDown, true);
407
+ (_this$unbindWindowCli = this.unbindWindowClick) === null || _this$unbindWindowCli === void 0 ? void 0 : _this$unbindWindowCli.call(this);
408
+ this.unbindWindowClick = null;
409
+ (_this$unbindWindowKey2 = this.unbindWindowKeydown) === null || _this$unbindWindowKey2 === void 0 ? void 0 : _this$unbindWindowKey2.call(this);
410
+ this.unbindWindowKeydown = null;
411
+ }
412
+ }, {
413
+ key: "componentDidUpdate",
414
+ value: function componentDidUpdate(prevProps) {
415
+ var isOpen = this.props.isOpen;
416
+
417
+ if (prevProps.isOpen !== isOpen) {
418
+ if (isOpen === true) {
419
+ this.open({
420
+ controlOverride: true
421
+ });
422
+ } else if (isOpen === false) {
423
+ this.close({
424
+ controlOverride: true
425
+ });
426
+ }
427
+ }
371
428
  } // Event Handlers
372
429
  // ==============================
373
430
 
374
431
  }, {
375
432
  key: "render",
376
433
  value: function render() {
377
- var _this2 = this;
434
+ var _this3 = this;
378
435
 
379
436
  var target = this.props.target;
380
437
  var isOpen = this.state.isOpen;
@@ -382,10 +439,10 @@ var PopupSelect = /*#__PURE__*/function (_PureComponent) {
382
439
  var ref = _ref3.ref;
383
440
  return target && target({
384
441
  isOpen: isOpen,
385
- ref: _this2.resolveTargetRef(ref),
442
+ ref: _this3.resolveTargetRef(ref),
386
443
  'aria-haspopup': 'true',
387
444
  'aria-expanded': isOpen,
388
- 'aria-controls': isOpen ? _this2.popperWrapperId : undefined
445
+ 'aria-controls': isOpen ? _this3.popperWrapperId : undefined
389
446
  });
390
447
  }), this.renderSelect());
391
448
  }
@@ -2,7 +2,7 @@ import Select from 'react-select';
2
2
  import { withAnalyticsEvents, withAnalyticsContext, createAndFireEvent } from '@atlaskit/analytics-next';
3
3
  import createSelect from './createSelect';
4
4
  var packageName = "@atlaskit/select";
5
- var packageVersion = "15.2.13";
5
+ var packageVersion = "15.3.2";
6
6
  export var SelectWithoutAnalytics = createSelect(Select);
7
7
  var createAndFireEventOnAtlaskit = createAndFireEvent('atlaskit');
8
8
  export default withAnalyticsContext({
@@ -18,7 +18,7 @@ export default function baseStyles(validationState, isCompact) {
18
18
  // react-select disables pointer events when isDisabled is true.
19
19
  // We override this and make the inner container turn it off instead.
20
20
  pointerEvents: 'all',
21
- cursor: isDisabled ? 'not-allowed' : undefined
21
+ cursor: isDisabled ? 'not-allowed' : css.cursor
22
22
  });
23
23
  },
24
24
  input: function input(css) {
@@ -164,14 +164,14 @@ export default function baseStyles(validationState, isCompact) {
164
164
  } else if (isSelected) {
165
165
  backgroundColor = "var(--ds-background-selected, ".concat(B50, ")");
166
166
  } else if (isFocused) {
167
- backgroundColor = "var(--ds-background-neutral-subtle-hovered, ".concat(N20, ")");
167
+ backgroundColor = "var(--ds-background-input-pressed, ".concat(N20, ")");
168
168
  }
169
169
 
170
170
  if (!isDisabled && (isFocused || isSelected)) {
171
171
  boxShadow = "inset 2px 0px 0px ".concat("var(--ds-border-selected, ".concat(B400, ")"));
172
172
  }
173
173
 
174
- var cursor = isDisabled ? 'not-allowed' : undefined;
174
+ var cursor = isDisabled ? 'not-allowed' : css.cursor;
175
175
  return _objectSpread(_objectSpread({}, css), {}, {
176
176
  padding: '6px 12px',
177
177
  backgroundColor: backgroundColor,
@@ -217,7 +217,7 @@ export default function baseStyles(validationState, isCompact) {
217
217
  return _objectSpread(_objectSpread({}, css), {}, {
218
218
  borderRadius: '2px',
219
219
  backgroundColor: isFocused ? "var(--ds-background-selected, ".concat(N40, ")") : "var(--ds-background-neutral-subtle-hovered, ".concat(N40, ")"),
220
- boxShadow: isFocused ? "0 0 0 2px ".concat("var(--ds-surface, transparent)", ", 0 0 0 4px ").concat("var(--ds-border-focused, transparent)") : 'none',
220
+ boxShadow: isFocused ? "0 0 0 2px ".concat("var(--ds-surface, transparent)", ", 0 0 0 4px ", "var(--ds-border-focused, transparent)") : 'none',
221
221
  maxWidth: '100%',
222
222
  '@media screen and (-ms-high-contrast: active)': {
223
223
  border: isFocused ? '1px solid transparent' : 'none'
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/select",
3
- "version": "15.2.13",
3
+ "version": "15.3.2",
4
4
  "sideEffects": false
5
5
  }
@@ -3,6 +3,7 @@ import Select from 'react-select';
3
3
  import { FocusTrap } from 'focus-trap';
4
4
  import { PopperProps } from 'react-popper';
5
5
  import { OptionType, ActionMeta, ReactSelectProps, StylesConfig, ValueType } from '../types';
6
+ import { UnbindFn } from 'bind-event-listener';
6
7
  declare type defaultModifiers = 'offset' | 'preventOverflow';
7
8
  declare type PopperPropsNoChildren<Modifiers> = Omit<PopperProps<Modifiers>, 'children'>;
8
9
  interface PopupSelectTriggerProps {
@@ -12,13 +13,53 @@ interface PopupSelectTriggerProps {
12
13
  'aria-controls'?: string;
13
14
  }
14
15
  export interface PopupSelectProps<Option = OptionType, IsMulti extends boolean = false, Modifiers = string> extends ReactSelectProps<Option, IsMulti> {
16
+ /**
17
+ * Defines whether the menu should close when selected. Defaults to "true"
18
+ */
15
19
  closeMenuOnSelect?: boolean;
20
+ /**
21
+ * The footer content shown at the bottom of the Popup, underneath the Select options
22
+ */
16
23
  footer?: ReactNode;
24
+ /**
25
+ The props passed down to React Popper.
26
+
27
+ Use these to override the default positioning strategy, behaviour and placement used by this library.
28
+ For more information, see the [React Popper documentation](https://popper.js.org/react-popper/v2/render-props).
29
+
30
+ */
17
31
  popperProps?: PopperPropsNoChildren<Modifiers>;
32
+ /**
33
+ * The maximum number of options the Select can contain without rendering the search field.
34
+ */
18
35
  searchThreshold?: number;
36
+ /**
37
+ * The maximum width for the popup menu. Can be a number, representing width in pixels,
38
+ * or a string containing a CSS length datatype.
39
+ */
40
+ maxMenuWidth?: number | string;
41
+ /**
42
+ * The maximum width for the popup menu. Can be a number, representing width in pixels,
43
+ * or a string containing a CSS length datatype.
44
+ */
45
+ minMenuWidth?: number | string;
46
+ /**
47
+ Render props used to anchor the popup to your content.
48
+
49
+ Make this an interactive element, such as an @atlaskit/button component.
50
+
51
+ The provided render props in `options` are detailed below:
52
+ - `isOpen`: The current state of the popup.
53
+ Use this to change the appearance of your target based on the state of your component
54
+ - `ref`: Pass this ref to the element the Popup should be attached to
55
+ - `aria-haspopup`, `aria-expanded`, `aria-controls`: Spread these onto a target element to
56
+ ensure your experience is accessible
57
+ */
19
58
  target?: (options: PopupSelectTriggerProps & {
20
59
  isOpen: boolean;
21
60
  }) => ReactNode;
61
+ isOpen?: boolean;
62
+ defaultIsOpen?: boolean;
22
63
  }
23
64
  interface State<Modifiers = string> {
24
65
  isOpen: boolean;
@@ -30,7 +71,11 @@ export default class PopupSelect<Option = OptionType, IsMulti extends boolean =
30
71
  menuRef: HTMLElement | null;
31
72
  selectRef: Select<Option, IsMulti> | null;
32
73
  targetRef: HTMLElement | null;
74
+ unbindWindowClick: UnbindFn | null;
75
+ unbindWindowKeydown: UnbindFn | null;
33
76
  defaultStyles: StylesConfig<Option, IsMulti>;
77
+ isOpenControlled: boolean;
78
+ defaultOpenState: boolean | undefined;
34
79
  state: {
35
80
  isOpen: boolean;
36
81
  mergedComponents: {
@@ -55,12 +100,27 @@ export default class PopupSelect<Option = OptionType, IsMulti extends boolean =
55
100
  static getDerivedStateFromProps(props: PopupSelectProps<OptionType>, state: State): Partial<State<string>> | null;
56
101
  componentDidMount(): void;
57
102
  componentWillUnmount(): void;
103
+ componentDidUpdate(prevProps: PopupSelectProps<Option, IsMulti>): void;
58
104
  handleKeyDown: (event: KeyboardEvent) => void;
59
105
  handleClick: ({ target }: MouseEvent) => void;
60
106
  handleSelectChange: (value: ValueType<Option, IsMulti>, actionMeta: ActionMeta<Option>) => void;
61
- open: () => void;
107
+ /**
108
+ * Opens the popup
109
+ *
110
+ * @param options.controlOverride - Force the popup to open when it's open state is being controlled
111
+ */
112
+ open: (options?: {
113
+ controlOverride?: boolean | undefined;
114
+ } | undefined) => void;
62
115
  initialiseFocusTrap: () => void;
63
- close: () => void;
116
+ /**
117
+ * Closes the popup
118
+ *
119
+ * @param options.controlOverride - Force the popup to close when it's open state is being controlled
120
+ */
121
+ close: (options?: {
122
+ controlOverride?: boolean | undefined;
123
+ } | undefined) => void;
64
124
  resolveTargetRef: (popperRef: React.Ref<HTMLElement>) => (ref: HTMLElement) => void;
65
125
  resolveMenuRef: (popperRef: React.Ref<HTMLElement>) => (ref: HTMLElement) => void;
66
126
  getSelectRef: (ref: Select<Option, IsMulti>) => void;
@@ -2,8 +2,8 @@
2
2
  import { FC, ReactNode, CSSProperties } from 'react';
3
3
  import { ControlProps, MenuProps, OptionType } from '../types';
4
4
  interface MenuDialogProps {
5
- maxWidth: number;
6
- minWidth: number;
5
+ maxWidth?: number | string;
6
+ minWidth?: number | string;
7
7
  style: CSSProperties;
8
8
  children: ReactNode;
9
9
  id: string;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@atlaskit/select",
3
- "version": "15.2.13",
3
+ "version": "15.3.2",
4
4
  "description": "Select allows users to make a single selection or multiple selections from a list of options.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
7
7
  },
8
- "repository": "https://bitbucket.org/atlassian/atlassian-frontend",
8
+ "repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
9
9
  "author": "Atlassian Pty Ltd",
10
10
  "license": "Apache-2.0",
11
11
  "main": "dist/cjs/index.js",
@@ -19,7 +19,8 @@
19
19
  "deprecatedAutoEntryPoints": true,
20
20
  "releaseModel": "scheduled",
21
21
  "website": {
22
- "name": "Select"
22
+ "name": "Select",
23
+ "category": "Components"
23
24
  }
24
25
  },
25
26
  "dependencies": {
@@ -32,7 +33,8 @@
32
33
  "@babel/runtime": "^7.0.0",
33
34
  "@emotion/core": "^10.0.9",
34
35
  "@popperjs/core": "^2.9.1",
35
- "@types/react-select": "^4.0.13",
36
+ "@types/react-select": "^4.0.18",
37
+ "bind-event-listener": "^2.1.1",
36
38
  "focus-trap": "^2.4.5",
37
39
  "memoize-one": "^6.0.0",
38
40
  "react-fast-compare": "^3.2.0",
@@ -52,7 +54,7 @@
52
54
  "@atlaskit/docs": "*",
53
55
  "@atlaskit/drawer": "^7.1.0",
54
56
  "@atlaskit/form": "^8.5.0",
55
- "@atlaskit/logo": "^13.6.0",
57
+ "@atlaskit/logo": "^13.7.0",
56
58
  "@atlaskit/modal-dialog": "^12.2.0",
57
59
  "@atlaskit/section-message": "^6.0.0",
58
60
  "@atlaskit/ssr": "*",
@@ -72,6 +74,7 @@
72
74
  },
73
75
  "techstack": {
74
76
  "@repo/internal": {
77
+ "dom-events": "use-bind-event-listener",
75
78
  "theming": "tokens",
76
79
  "deprecation": "no-deprecated-imports",
77
80
  "styling": [