@atlaskit/react-select 2.1.0 → 2.2.1

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 (109) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/emotion/components/containers.js +111 -0
  3. package/dist/cjs/emotion/components/control.js +110 -0
  4. package/dist/cjs/emotion/components/group.js +71 -0
  5. package/dist/cjs/emotion/components/index.js +52 -0
  6. package/dist/cjs/emotion/components/indicators.js +137 -0
  7. package/dist/cjs/emotion/components/input.js +94 -0
  8. package/dist/cjs/emotion/components/internal/a11y-text.js +36 -0
  9. package/dist/cjs/emotion/components/internal/dummy-input.js +44 -0
  10. package/dist/cjs/emotion/components/internal/index.js +34 -0
  11. package/dist/cjs/emotion/components/internal/notify-open-layer-observer.js +21 -0
  12. package/dist/cjs/emotion/components/internal/required-input.js +43 -0
  13. package/dist/cjs/emotion/components/internal/scroll-manager.js +57 -0
  14. package/dist/cjs/emotion/components/internal/use-scroll-capture.js +132 -0
  15. package/dist/cjs/emotion/components/internal/use-scroll-lock.js +149 -0
  16. package/dist/cjs/emotion/components/live-region.js +182 -0
  17. package/dist/cjs/emotion/components/menu.js +456 -0
  18. package/dist/cjs/emotion/components/multi-value.js +224 -0
  19. package/dist/cjs/emotion/components/option.js +82 -0
  20. package/dist/cjs/emotion/components/placeholder.js +34 -0
  21. package/dist/cjs/emotion/components/single-value.js +40 -0
  22. package/dist/cjs/select.js +11 -8
  23. package/dist/es2019/emotion/components/containers.js +109 -0
  24. package/dist/es2019/emotion/components/control.js +107 -0
  25. package/dist/es2019/emotion/components/group.js +59 -0
  26. package/dist/es2019/emotion/components/index.js +41 -0
  27. package/dist/es2019/emotion/components/indicators.js +128 -0
  28. package/dist/es2019/emotion/components/input.js +86 -0
  29. package/dist/es2019/emotion/components/internal/a11y-text.js +27 -0
  30. package/dist/es2019/emotion/components/internal/dummy-input.js +37 -0
  31. package/dist/es2019/emotion/components/internal/index.js +4 -0
  32. package/dist/es2019/emotion/components/internal/notify-open-layer-observer.js +16 -0
  33. package/dist/es2019/emotion/components/internal/required-input.js +35 -0
  34. package/dist/es2019/emotion/components/internal/scroll-manager.js +49 -0
  35. package/dist/es2019/emotion/components/internal/use-scroll-capture.js +128 -0
  36. package/dist/es2019/emotion/components/internal/use-scroll-lock.js +143 -0
  37. package/dist/es2019/emotion/components/live-region.js +178 -0
  38. package/dist/es2019/emotion/components/menu.js +450 -0
  39. package/dist/es2019/emotion/components/multi-value.js +227 -0
  40. package/dist/es2019/emotion/components/option.js +78 -0
  41. package/dist/es2019/emotion/components/placeholder.js +28 -0
  42. package/dist/es2019/emotion/components/single-value.js +34 -0
  43. package/dist/es2019/select.js +11 -8
  44. package/dist/esm/emotion/components/containers.js +105 -0
  45. package/dist/esm/emotion/components/control.js +103 -0
  46. package/dist/esm/emotion/components/group.js +65 -0
  47. package/dist/esm/emotion/components/index.js +43 -0
  48. package/dist/esm/emotion/components/indicators.js +132 -0
  49. package/dist/esm/emotion/components/input.js +89 -0
  50. package/dist/esm/emotion/components/internal/a11y-text.js +29 -0
  51. package/dist/esm/emotion/components/internal/dummy-input.js +38 -0
  52. package/dist/esm/emotion/components/internal/index.js +4 -0
  53. package/dist/esm/emotion/components/internal/notify-open-layer-observer.js +15 -0
  54. package/dist/esm/emotion/components/internal/required-input.js +36 -0
  55. package/dist/esm/emotion/components/internal/scroll-manager.js +49 -0
  56. package/dist/esm/emotion/components/internal/use-scroll-capture.js +126 -0
  57. package/dist/esm/emotion/components/internal/use-scroll-lock.js +143 -0
  58. package/dist/esm/emotion/components/live-region.js +175 -0
  59. package/dist/esm/emotion/components/menu.js +454 -0
  60. package/dist/esm/emotion/components/multi-value.js +217 -0
  61. package/dist/esm/emotion/components/option.js +75 -0
  62. package/dist/esm/emotion/components/placeholder.js +27 -0
  63. package/dist/esm/emotion/components/single-value.js +33 -0
  64. package/dist/esm/select.js +11 -8
  65. package/dist/types/components/internal/notify-open-layer-observer.d.ts +4 -2
  66. package/dist/types/emotion/components/containers.d.ts +54 -0
  67. package/dist/types/emotion/components/control.d.ts +42 -0
  68. package/dist/types/emotion/components/group.d.ts +52 -0
  69. package/dist/types/emotion/components/index.d.ts +67 -0
  70. package/dist/types/emotion/components/indicators.d.ts +73 -0
  71. package/dist/types/emotion/components/input.d.ts +37 -0
  72. package/dist/types/emotion/components/internal/a11y-text.d.ts +8 -0
  73. package/dist/types/emotion/components/internal/dummy-input.d.ts +9 -0
  74. package/dist/types/emotion/components/internal/index.d.ts +4 -0
  75. package/dist/types/emotion/components/internal/notify-open-layer-observer.d.ts +11 -0
  76. package/dist/types/emotion/components/internal/required-input.d.ts +10 -0
  77. package/dist/types/emotion/components/internal/scroll-manager.d.ts +17 -0
  78. package/dist/types/emotion/components/internal/use-scroll-capture.d.ts +12 -0
  79. package/dist/types/emotion/components/internal/use-scroll-lock.d.ts +9 -0
  80. package/dist/types/emotion/components/live-region.d.ts +25 -0
  81. package/dist/types/emotion/components/menu.d.ts +116 -0
  82. package/dist/types/emotion/components/multi-value.d.ts +47 -0
  83. package/dist/types/emotion/components/option.d.ts +49 -0
  84. package/dist/types/emotion/components/placeholder.d.ts +22 -0
  85. package/dist/types/emotion/components/single-value.d.ts +28 -0
  86. package/dist/types/select.d.ts +7 -4
  87. package/dist/types-ts4.5/components/internal/notify-open-layer-observer.d.ts +4 -2
  88. package/dist/types-ts4.5/emotion/components/containers.d.ts +54 -0
  89. package/dist/types-ts4.5/emotion/components/control.d.ts +42 -0
  90. package/dist/types-ts4.5/emotion/components/group.d.ts +52 -0
  91. package/dist/types-ts4.5/emotion/components/index.d.ts +67 -0
  92. package/dist/types-ts4.5/emotion/components/indicators.d.ts +73 -0
  93. package/dist/types-ts4.5/emotion/components/input.d.ts +37 -0
  94. package/dist/types-ts4.5/emotion/components/internal/a11y-text.d.ts +8 -0
  95. package/dist/types-ts4.5/emotion/components/internal/dummy-input.d.ts +9 -0
  96. package/dist/types-ts4.5/emotion/components/internal/index.d.ts +4 -0
  97. package/dist/types-ts4.5/emotion/components/internal/notify-open-layer-observer.d.ts +11 -0
  98. package/dist/types-ts4.5/emotion/components/internal/required-input.d.ts +10 -0
  99. package/dist/types-ts4.5/emotion/components/internal/scroll-manager.d.ts +17 -0
  100. package/dist/types-ts4.5/emotion/components/internal/use-scroll-capture.d.ts +12 -0
  101. package/dist/types-ts4.5/emotion/components/internal/use-scroll-lock.d.ts +9 -0
  102. package/dist/types-ts4.5/emotion/components/live-region.d.ts +25 -0
  103. package/dist/types-ts4.5/emotion/components/menu.d.ts +116 -0
  104. package/dist/types-ts4.5/emotion/components/multi-value.d.ts +47 -0
  105. package/dist/types-ts4.5/emotion/components/option.d.ts +49 -0
  106. package/dist/types-ts4.5/emotion/components/placeholder.d.ts +22 -0
  107. package/dist/types-ts4.5/emotion/components/single-value.d.ts +28 -0
  108. package/dist/types-ts4.5/select.d.ts +7 -4
  109. package/package.json +3 -3
@@ -0,0 +1,143 @@
1
+ import { useCallback, useEffect, useRef } from 'react';
2
+ var STYLE_KEYS = ['boxSizing', 'height', 'overflow', 'paddingRight', 'position'];
3
+ var LOCK_STYLES = {
4
+ boxSizing: 'border-box',
5
+ // account for possible declaration `width: 100%;` on body
6
+ overflow: 'hidden',
7
+ position: 'relative',
8
+ height: '100%'
9
+ };
10
+ function preventTouchMove(e) {
11
+ e.preventDefault();
12
+ }
13
+ function allowTouchMove(e) {
14
+ e.stopPropagation();
15
+ }
16
+ function preventInertiaScroll() {
17
+ var top = this.scrollTop;
18
+ var totalScroll = this.scrollHeight;
19
+ var currentScroll = top + this.offsetHeight;
20
+ if (top === 0) {
21
+ this.scrollTop = 1;
22
+ } else if (currentScroll === totalScroll) {
23
+ this.scrollTop = top - 1;
24
+ }
25
+ }
26
+
27
+ // `ontouchstart` check works on most browsers
28
+ // `maxTouchPoints` works on IE10/11 and Surface
29
+ function isTouchDevice() {
30
+ // eslint-disable-next-line compat/compat
31
+ return 'ontouchstart' in window || navigator.maxTouchPoints;
32
+ }
33
+ var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
34
+ var activeScrollLocks = 0;
35
+ var listenerOptions = {
36
+ capture: false,
37
+ passive: false
38
+ };
39
+
40
+ // TODO: Fill in the hook {description}.
41
+ /**
42
+ * {description}.
43
+ */
44
+ export default function useScrollLock(_ref) {
45
+ var isEnabled = _ref.isEnabled,
46
+ _ref$accountForScroll = _ref.accountForScrollbars,
47
+ accountForScrollbars = _ref$accountForScroll === void 0 ? true : _ref$accountForScroll;
48
+ var originalStyles = useRef({});
49
+ var scrollTarget = useRef(null);
50
+ var addScrollLock = useCallback(function (touchScrollTarget) {
51
+ if (!canUseDOM) {
52
+ return;
53
+ }
54
+ var target = document.body;
55
+ var targetStyle = target && target.style;
56
+ if (accountForScrollbars) {
57
+ // store any styles already applied to the body
58
+ STYLE_KEYS.forEach(function (key) {
59
+ var val = targetStyle && targetStyle[key];
60
+ originalStyles.current[key] = val;
61
+ });
62
+ }
63
+
64
+ // apply the lock styles and padding if this is the first scroll lock
65
+ if (accountForScrollbars && activeScrollLocks < 1) {
66
+ var currentPadding = parseInt(originalStyles.current.paddingRight, 10) || 0;
67
+ var clientWidth = document.body ? document.body.clientWidth : 0;
68
+ var adjustedPadding = window.innerWidth - clientWidth + currentPadding || 0;
69
+ Object.keys(LOCK_STYLES).forEach(function (key) {
70
+ var val = LOCK_STYLES[key];
71
+ if (targetStyle) {
72
+ targetStyle[key] = val;
73
+ }
74
+ });
75
+ if (targetStyle) {
76
+ targetStyle.paddingRight = "".concat(adjustedPadding, "px");
77
+ }
78
+ }
79
+
80
+ // account for touch devices
81
+ if (target && isTouchDevice()) {
82
+ // Mobile Safari ignores { overflow: hidden } declaration on the body.
83
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
84
+ target.addEventListener('touchmove', preventTouchMove, listenerOptions);
85
+
86
+ // Allow scroll on provided target
87
+ if (touchScrollTarget) {
88
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
89
+ touchScrollTarget.addEventListener('touchstart', preventInertiaScroll, listenerOptions);
90
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
91
+ touchScrollTarget.addEventListener('touchmove', allowTouchMove, listenerOptions);
92
+ }
93
+ }
94
+
95
+ // increment active scroll locks
96
+ activeScrollLocks += 1;
97
+ }, [accountForScrollbars]);
98
+ var removeScrollLock = useCallback(function (touchScrollTarget) {
99
+ if (!canUseDOM) {
100
+ return;
101
+ }
102
+ var target = document.body;
103
+ var targetStyle = target && target.style;
104
+
105
+ // safely decrement active scroll locks
106
+ activeScrollLocks = Math.max(activeScrollLocks - 1, 0);
107
+
108
+ // reapply original body styles, if any
109
+ if (accountForScrollbars && activeScrollLocks < 1) {
110
+ STYLE_KEYS.forEach(function (key) {
111
+ var val = originalStyles.current[key];
112
+ if (targetStyle) {
113
+ targetStyle[key] = val;
114
+ }
115
+ });
116
+ }
117
+
118
+ // remove touch listeners
119
+ if (target && isTouchDevice()) {
120
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
121
+ target.removeEventListener('touchmove', preventTouchMove, listenerOptions);
122
+ if (touchScrollTarget) {
123
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
124
+ touchScrollTarget.removeEventListener('touchstart', preventInertiaScroll, listenerOptions);
125
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
126
+ touchScrollTarget.removeEventListener('touchmove', allowTouchMove, listenerOptions);
127
+ }
128
+ }
129
+ }, [accountForScrollbars]);
130
+ useEffect(function () {
131
+ if (!isEnabled) {
132
+ return;
133
+ }
134
+ var element = scrollTarget.current;
135
+ addScrollLock(element);
136
+ return function () {
137
+ removeScrollLock(element);
138
+ };
139
+ }, [isEnabled, addScrollLock, removeScrollLock]);
140
+ return function (element) {
141
+ scrollTarget.current = element;
142
+ };
143
+ }
@@ -0,0 +1,175 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ 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; }
3
+ 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; }
4
+ /* eslint-disable @atlaskit/platform/ensure-feature-flag-prefix */
5
+ /**
6
+ * @jsxRuntime classic
7
+ * @jsx jsx
8
+ * @jsxFrag React.Fragment
9
+ */
10
+ import React, { Fragment, useMemo, useRef } from 'react';
11
+ import { jsx } from '@emotion/react';
12
+ import { fg } from '@atlaskit/platform-feature-flags';
13
+ import { defaultAriaLiveMessages } from '../../accessibility';
14
+ import A11yText from './internal/a11y-text';
15
+
16
+ // ==============================
17
+ // Root Container
18
+ // ==============================
19
+
20
+ // eslint-disable-next-line @repo/internal/react/require-jsdoc
21
+ var LiveRegion = function LiveRegion(props) {
22
+ var ariaSelection = props.ariaSelection,
23
+ focusedOption = props.focusedOption,
24
+ focusedValue = props.focusedValue,
25
+ focusableOptions = props.focusableOptions,
26
+ isFocused = props.isFocused,
27
+ selectValue = props.selectValue,
28
+ selectProps = props.selectProps,
29
+ id = props.id,
30
+ isAppleDevice = props.isAppleDevice;
31
+ var ariaLiveMessages = selectProps.ariaLiveMessages,
32
+ getOptionLabel = selectProps.getOptionLabel,
33
+ inputValue = selectProps.inputValue,
34
+ isMulti = selectProps.isMulti,
35
+ isOptionDisabled = selectProps.isOptionDisabled,
36
+ isSearchable = selectProps.isSearchable,
37
+ label = selectProps.label,
38
+ menuIsOpen = selectProps.menuIsOpen,
39
+ options = selectProps.options,
40
+ screenReaderStatus = selectProps.screenReaderStatus,
41
+ tabSelectsValue = selectProps.tabSelectsValue,
42
+ isLoading = selectProps.isLoading;
43
+ var ariaLabel = selectProps['aria-label'] || label;
44
+ var ariaLive = selectProps['aria-live'];
45
+
46
+ // for safari, we will use minimum support from aria-live region
47
+ var isA11yImprovementEnabled = fg('design_system_select-a11y-improvement') && !isAppleDevice;
48
+
49
+ // Update aria live message configuration when prop changes
50
+ var messages = useMemo(function () {
51
+ return _objectSpread(_objectSpread({}, defaultAriaLiveMessages), ariaLiveMessages || {});
52
+ }, [ariaLiveMessages]);
53
+
54
+ // Update aria live selected option when prop changes
55
+ var ariaSelected = useMemo(function () {
56
+ var message = '';
57
+ if (isA11yImprovementEnabled && menuIsOpen) {
58
+ // we don't need to have selected message when the menu is open
59
+ return '';
60
+ }
61
+ if (ariaSelection && messages.onChange) {
62
+ var option = ariaSelection.option,
63
+ selectedOptions = ariaSelection.options,
64
+ removedValue = ariaSelection.removedValue,
65
+ removedValues = ariaSelection.removedValues,
66
+ value = ariaSelection.value;
67
+ // select-option when !isMulti does not return option so we assume selected option is value
68
+ var asOption = function asOption(val) {
69
+ return !Array.isArray(val) ? val : null;
70
+ };
71
+
72
+ // If there is just one item from the action then get its label
73
+ var selected = removedValue || option || asOption(value);
74
+ var _label = selected ? getOptionLabel(selected) : '';
75
+
76
+ // If there are multiple items from the action then return an array of labels
77
+ var multiSelected = selectedOptions || removedValues || undefined;
78
+ var labels = multiSelected ? multiSelected.map(getOptionLabel) : [];
79
+ if (isA11yImprovementEnabled && !_label && !labels.length) {
80
+ // return empty string if no labels provided
81
+ return '';
82
+ }
83
+ var onChangeProps = _objectSpread({
84
+ // multiSelected items are usually items that have already been selected
85
+ // or set by the user as a default value so we assume they are not disabled
86
+ isDisabled: selected && isOptionDisabled(selected, selectValue),
87
+ label: _label,
88
+ labels: labels
89
+ }, ariaSelection);
90
+ message = messages.onChange(onChangeProps);
91
+ }
92
+ return message;
93
+ }, [ariaSelection, messages, isOptionDisabled, selectValue, getOptionLabel, isA11yImprovementEnabled, menuIsOpen]);
94
+ var prevInputValue = useRef('');
95
+ var ariaFocused = useMemo(function () {
96
+ var focusMsg = '';
97
+ var focused = focusedOption || focusedValue;
98
+ var isSelected = !!(focusedOption && selectValue && selectValue.includes(focusedOption));
99
+ if (inputValue === prevInputValue.current && isA11yImprovementEnabled) {
100
+ // only announce focus option when searching when ff is on and the input value changed
101
+ // for safari, we will announce for all
102
+ return '';
103
+ }
104
+ if (focused && messages.onFocus) {
105
+ var onFocusProps = {
106
+ focused: focused,
107
+ label: getOptionLabel(focused),
108
+ isDisabled: isOptionDisabled(focused, selectValue),
109
+ isSelected: isSelected,
110
+ options: focusableOptions,
111
+ context: focused === focusedOption ? 'menu' : 'value',
112
+ selectValue: selectValue,
113
+ isMulti: isMulti
114
+ };
115
+ focusMsg = messages.onFocus(onFocusProps);
116
+ }
117
+ prevInputValue.current = inputValue;
118
+ return focusMsg;
119
+ }, [inputValue, focusedOption, focusedValue, getOptionLabel, isOptionDisabled, messages, focusableOptions, selectValue, isA11yImprovementEnabled, isMulti]);
120
+ var ariaResults = useMemo(function () {
121
+ var resultsMsg = '';
122
+ if (menuIsOpen && options.length && !isLoading && messages.onFilter) {
123
+ var resultsMessage = screenReaderStatus({
124
+ count: focusableOptions.length
125
+ });
126
+ resultsMsg = messages.onFilter({
127
+ inputValue: inputValue,
128
+ resultsMessage: resultsMessage
129
+ });
130
+ }
131
+ return resultsMsg;
132
+ }, [focusableOptions, inputValue, menuIsOpen, messages, options, screenReaderStatus, isLoading]);
133
+ var isInitialFocus = (ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action) === 'initial-input-focus';
134
+ var ariaGuidance = useMemo(function () {
135
+ if (fg('design_system_select-a11y-improvement')) {
136
+ // don't announce guidance at all when ff is on
137
+ return '';
138
+ }
139
+ var guidanceMsg = '';
140
+ if (messages.guidance) {
141
+ var context = focusedValue ? 'value' : menuIsOpen ? 'menu' : 'input';
142
+ guidanceMsg = messages.guidance({
143
+ 'aria-label': ariaLabel,
144
+ context: context,
145
+ isDisabled: focusedOption && isOptionDisabled(focusedOption, selectValue),
146
+ isMulti: isMulti,
147
+ isSearchable: isSearchable,
148
+ tabSelectsValue: tabSelectsValue,
149
+ isInitialFocus: isInitialFocus
150
+ });
151
+ }
152
+ return guidanceMsg;
153
+ }, [ariaLabel, focusedOption, focusedValue, isMulti, isOptionDisabled, isSearchable, menuIsOpen, messages, selectValue, tabSelectsValue, isInitialFocus]);
154
+ var ScreenReaderText = jsx(Fragment, null, jsx("span", {
155
+ id: "aria-selection"
156
+ }, ariaSelected), jsx("span", {
157
+ id: "aria-results"
158
+ }, ariaResults), !fg('design_system_select-a11y-improvement') && jsx(React.Fragment, null, jsx("span", {
159
+ id: "aria-focused"
160
+ }, ariaFocused), jsx("span", {
161
+ id: "aria-guidance"
162
+ }, ariaGuidance)));
163
+ return jsx(Fragment, null, jsx(A11yText, {
164
+ id: id
165
+ }, isInitialFocus && ScreenReaderText), jsx(A11yText, {
166
+ "aria-live": ariaLive // Should be undefined by default unless a specific use case requires it
167
+ ,
168
+ "aria-atomic": fg('design_system_select-a11y-improvement') ? undefined : 'false',
169
+ "aria-relevant": fg('design_system_select-a11y-improvement') ? undefined : 'additions text',
170
+ role: fg('design_system_select-a11y-improvement') ? 'status' : 'log'
171
+ }, isFocused && !isInitialFocus && ScreenReaderText));
172
+ };
173
+
174
+ // eslint-disable-next-line @repo/internal/react/require-jsdoc
175
+ export default LiveRegion;