@primer/components 30.3.0-rc.2010c7d4 → 31.0.0-rc.15aa0a10

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 (180) hide show
  1. package/.eslintrc.json +2 -1
  2. package/.storybook/preview.js +4 -4
  3. package/CHANGELOG.md +12 -2
  4. package/codemods/deprecateUtilityComponents.js +1 -1
  5. package/contributor-docs/adrs/adr-003-prop-norms.md +72 -0
  6. package/dist/browser.esm.js +798 -794
  7. package/dist/browser.esm.js.map +1 -1
  8. package/dist/browser.umd.js +801 -797
  9. package/dist/browser.umd.js.map +1 -1
  10. package/docs/content/Autocomplete.mdx +627 -0
  11. package/docs/content/TextInputTokens.mdx +89 -0
  12. package/docs/content/getting-started.md +1 -1
  13. package/docs/content/overriding-styles.mdx +7 -6
  14. package/docs/content/theming.md +5 -5
  15. package/docs/package-lock.json +288 -511
  16. package/docs/package.json +1 -1
  17. package/docs/src/@primer/gatsby-theme-doctocat/components/hero.js +14 -12
  18. package/docs/src/@primer/gatsby-theme-doctocat/nav.yml +2 -0
  19. package/docs/src/@primer/gatsby-theme-doctocat/primer-components-hero.svg +7 -7
  20. package/lib/ActionList/Item.js +1 -1
  21. package/lib/AnchoredOverlay/AnchoredOverlay.d.ts +2 -1
  22. package/lib/AnchoredOverlay/AnchoredOverlay.js +11 -3
  23. package/lib/Autocomplete/Autocomplete.d.ts +304 -0
  24. package/lib/Autocomplete/Autocomplete.js +145 -0
  25. package/lib/Autocomplete/AutocompleteContext.d.ts +17 -0
  26. package/lib/Autocomplete/AutocompleteContext.js +11 -0
  27. package/lib/Autocomplete/AutocompleteInput.d.ts +292 -0
  28. package/lib/Autocomplete/AutocompleteInput.js +157 -0
  29. package/lib/Autocomplete/AutocompleteMenu.d.ts +72 -0
  30. package/lib/Autocomplete/AutocompleteMenu.js +224 -0
  31. package/lib/Autocomplete/AutocompleteOverlay.d.ts +20 -0
  32. package/lib/Autocomplete/AutocompleteOverlay.js +80 -0
  33. package/lib/Autocomplete/index.d.ts +2 -0
  34. package/lib/Autocomplete/index.js +15 -0
  35. package/lib/BaseStyles.js +1 -1
  36. package/lib/BorderBox.js +1 -1
  37. package/lib/Button/ButtonInvisible.js +1 -1
  38. package/lib/Caret.js +2 -2
  39. package/lib/Dialog.js +1 -1
  40. package/lib/FilteredActionList/FilteredActionList.js +5 -31
  41. package/lib/Flash.js +16 -16
  42. package/lib/Label.js +1 -1
  43. package/lib/Overlay.d.ts +1 -0
  44. package/lib/Overlay.js +3 -1
  45. package/lib/ProgressBar.js +1 -1
  46. package/lib/StateLabel.js +13 -19
  47. package/lib/Token/_RemoveTokenButton.js +1 -1
  48. package/lib/__tests__/Autocomplete.test.d.ts +1 -0
  49. package/lib/__tests__/Autocomplete.test.js +528 -0
  50. package/lib/__tests__/BorderBox.test.js +1 -1
  51. package/lib/__tests__/CircleOcticon.test.js +1 -1
  52. package/lib/__tests__/CounterLabel.test.js +4 -4
  53. package/lib/__tests__/Flash.test.js +4 -4
  54. package/lib/__tests__/Link.test.js +1 -1
  55. package/lib/__tests__/behaviors/scrollIntoViewingArea.test.d.ts +1 -0
  56. package/lib/__tests__/behaviors/scrollIntoViewingArea.test.js +226 -0
  57. package/lib/behaviors/scrollIntoViewingArea.d.ts +1 -0
  58. package/lib/behaviors/scrollIntoViewingArea.js +39 -0
  59. package/lib/hooks/useOpenAndCloseFocus.d.ts +2 -1
  60. package/lib/hooks/useOpenAndCloseFocus.js +7 -2
  61. package/lib/hooks/useOverlay.d.ts +2 -1
  62. package/lib/hooks/useOverlay.js +4 -2
  63. package/lib/index.d.ts +2 -0
  64. package/lib/index.js +8 -0
  65. package/lib/stories/Autocomplete.stories.js +608 -0
  66. package/lib/stories/Dialog.stories.js +3 -3
  67. package/lib/stories/IssueLabelToken.stories.js +1 -1
  68. package/lib/stories/ProfileToken.stories.js +1 -1
  69. package/lib/theme-preval.js +370 -3100
  70. package/lib/utils/testing.d.ts +50 -493
  71. package/lib/utils/types/MandateProps.d.ts +3 -0
  72. package/lib/utils/types/MandateProps.js +1 -0
  73. package/lib/utils/types/index.d.ts +1 -0
  74. package/lib/utils/types/index.js +13 -0
  75. package/lib-esm/ActionList/Item.js +1 -1
  76. package/lib-esm/AnchoredOverlay/AnchoredOverlay.d.ts +2 -1
  77. package/lib-esm/AnchoredOverlay/AnchoredOverlay.js +11 -3
  78. package/lib-esm/Autocomplete/Autocomplete.d.ts +304 -0
  79. package/lib-esm/Autocomplete/Autocomplete.js +123 -0
  80. package/lib-esm/Autocomplete/AutocompleteContext.d.ts +17 -0
  81. package/lib-esm/Autocomplete/AutocompleteContext.js +2 -0
  82. package/lib-esm/Autocomplete/AutocompleteInput.d.ts +292 -0
  83. package/lib-esm/Autocomplete/AutocompleteInput.js +138 -0
  84. package/lib-esm/Autocomplete/AutocompleteMenu.d.ts +72 -0
  85. package/lib-esm/Autocomplete/AutocompleteMenu.js +205 -0
  86. package/lib-esm/Autocomplete/AutocompleteOverlay.d.ts +20 -0
  87. package/lib-esm/Autocomplete/AutocompleteOverlay.js +62 -0
  88. package/lib-esm/Autocomplete/index.d.ts +2 -0
  89. package/lib-esm/Autocomplete/index.js +1 -0
  90. package/lib-esm/BaseStyles.js +1 -1
  91. package/lib-esm/BorderBox.js +1 -1
  92. package/lib-esm/Button/ButtonInvisible.js +1 -1
  93. package/lib-esm/Caret.js +2 -2
  94. package/lib-esm/Dialog.js +1 -1
  95. package/lib-esm/FilteredActionList/FilteredActionList.js +3 -31
  96. package/lib-esm/Flash.js +16 -16
  97. package/lib-esm/Label.js +1 -1
  98. package/lib-esm/Overlay.d.ts +1 -0
  99. package/lib-esm/Overlay.js +3 -1
  100. package/lib-esm/ProgressBar.js +1 -1
  101. package/lib-esm/StateLabel.js +13 -19
  102. package/lib-esm/Token/_RemoveTokenButton.js +1 -1
  103. package/lib-esm/__tests__/Autocomplete.test.d.ts +1 -0
  104. package/lib-esm/__tests__/Autocomplete.test.js +494 -0
  105. package/lib-esm/__tests__/BorderBox.test.js +1 -1
  106. package/lib-esm/__tests__/CircleOcticon.test.js +1 -1
  107. package/lib-esm/__tests__/CounterLabel.test.js +4 -4
  108. package/lib-esm/__tests__/Flash.test.js +4 -4
  109. package/lib-esm/__tests__/Link.test.js +1 -1
  110. package/lib-esm/__tests__/behaviors/scrollIntoViewingArea.test.d.ts +1 -0
  111. package/lib-esm/__tests__/behaviors/scrollIntoViewingArea.test.js +224 -0
  112. package/lib-esm/behaviors/scrollIntoViewingArea.d.ts +1 -0
  113. package/lib-esm/behaviors/scrollIntoViewingArea.js +30 -0
  114. package/lib-esm/hooks/useOpenAndCloseFocus.d.ts +2 -1
  115. package/lib-esm/hooks/useOpenAndCloseFocus.js +7 -2
  116. package/lib-esm/hooks/useOverlay.d.ts +2 -1
  117. package/lib-esm/hooks/useOverlay.js +4 -2
  118. package/lib-esm/index.d.ts +2 -0
  119. package/lib-esm/index.js +1 -0
  120. package/lib-esm/stories/Autocomplete.stories.js +549 -0
  121. package/lib-esm/stories/Dialog.stories.js +3 -3
  122. package/lib-esm/stories/IssueLabelToken.stories.js +1 -1
  123. package/lib-esm/stories/ProfileToken.stories.js +1 -1
  124. package/lib-esm/theme-preval.js +370 -3100
  125. package/lib-esm/utils/testing.d.ts +50 -493
  126. package/lib-esm/utils/types/MandateProps.d.ts +3 -0
  127. package/lib-esm/utils/types/MandateProps.js +1 -0
  128. package/lib-esm/utils/types/index.d.ts +1 -0
  129. package/lib-esm/utils/types/index.js +2 -1
  130. package/package-lock.json +11 -8
  131. package/package.json +3 -3
  132. package/src/ActionList/Item.tsx +1 -1
  133. package/src/AnchoredOverlay/AnchoredOverlay.tsx +14 -3
  134. package/src/Autocomplete/Autocomplete.tsx +103 -0
  135. package/src/Autocomplete/AutocompleteContext.tsx +19 -0
  136. package/src/Autocomplete/AutocompleteInput.tsx +179 -0
  137. package/src/Autocomplete/AutocompleteMenu.tsx +341 -0
  138. package/src/Autocomplete/AutocompleteOverlay.tsx +68 -0
  139. package/src/Autocomplete/index.ts +2 -0
  140. package/src/BaseStyles.tsx +1 -1
  141. package/src/BorderBox.tsx +1 -1
  142. package/src/Button/ButtonInvisible.tsx +7 -2
  143. package/src/Caret.tsx +2 -2
  144. package/src/Dialog.tsx +1 -1
  145. package/src/FilteredActionList/FilteredActionList.tsx +10 -25
  146. package/src/Flash.tsx +16 -16
  147. package/src/Label.tsx +1 -1
  148. package/src/Overlay.tsx +4 -1
  149. package/src/ProgressBar.tsx +1 -1
  150. package/src/StateLabel.tsx +12 -20
  151. package/src/Token/_RemoveTokenButton.tsx +4 -2
  152. package/src/__tests__/Autocomplete.test.tsx +444 -0
  153. package/src/__tests__/BorderBox.test.tsx +1 -1
  154. package/src/__tests__/CircleOcticon.test.tsx +1 -1
  155. package/src/__tests__/CounterLabel.test.tsx +4 -4
  156. package/src/__tests__/Flash.test.tsx +4 -4
  157. package/src/__tests__/Link.test.tsx +1 -1
  158. package/src/__tests__/__snapshots__/AnchoredOverlay.test.tsx.snap +3 -3
  159. package/src/__tests__/__snapshots__/Autocomplete.test.tsx.snap +3414 -0
  160. package/src/__tests__/__snapshots__/Button.test.tsx.snap +9 -1
  161. package/src/__tests__/__snapshots__/ConfirmationDialog.test.tsx.snap +1 -1
  162. package/src/__tests__/__snapshots__/SelectPanel.test.tsx.snap +1 -1
  163. package/src/__tests__/__snapshots__/StateLabel.test.tsx.snap +0 -21
  164. package/src/__tests__/__snapshots__/TextInputWithTokens.test.tsx.snap +16 -16
  165. package/src/__tests__/__snapshots__/Token.test.tsx.snap +34 -34
  166. package/src/__tests__/behaviors/scrollIntoViewingArea.test.ts +195 -0
  167. package/src/behaviors/scrollIntoViewingArea.ts +27 -0
  168. package/src/hooks/useOpenAndCloseFocus.ts +7 -2
  169. package/src/hooks/useOverlay.tsx +4 -2
  170. package/src/index.ts +2 -0
  171. package/src/stories/Autocomplete.stories.tsx +572 -0
  172. package/src/stories/Dialog.stories.tsx +3 -3
  173. package/src/stories/IssueLabelToken.stories.tsx +1 -1
  174. package/src/stories/ProfileToken.stories.tsx +1 -1
  175. package/src/utils/types/MandateProps.ts +19 -0
  176. package/src/utils/types/index.ts +1 -0
  177. package/stats.html +1 -1
  178. package/docs/src/@primer/gatsby-theme-doctocat/components/live-code.js +0 -84
  179. package/docs/src/@primer/gatsby-theme-doctocat/components/nav-dropdown.js +0 -48
  180. package/docs/src/@primer/gatsby-theme-doctocat/components/wrap-page-element.js +0 -25
@@ -0,0 +1,528 @@
1
+ "use strict";
2
+
3
+ var _react = _interopRequireDefault(require("react"));
4
+
5
+ var _testing = require("../utils/testing");
6
+
7
+ var _react2 = require("@testing-library/react");
8
+
9
+ var _jestAxe = require("jest-axe");
10
+
11
+ require("babel-polyfill");
12
+
13
+ var _Autocomplete = _interopRequireDefault(require("../Autocomplete"));
14
+
15
+ var _index = require("../index");
16
+
17
+ var _theme = _interopRequireDefault(require("../theme"));
18
+
19
+ var _BaseStyles = _interopRequireDefault(require("../BaseStyles"));
20
+
21
+ var _ThemeProvider = require("../ThemeProvider");
22
+
23
+ var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
24
+
25
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26
+
27
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
28
+
29
+ expect.extend(_jestAxe.toHaveNoViolations);
30
+ const mockItems = [{
31
+ text: 'zero',
32
+ id: 0
33
+ }, {
34
+ text: 'one',
35
+ id: 1
36
+ }, {
37
+ text: 'two',
38
+ id: 2
39
+ }, {
40
+ text: 'three',
41
+ id: 3
42
+ }, {
43
+ text: 'four',
44
+ id: 4
45
+ }, {
46
+ text: 'five',
47
+ id: 5
48
+ }, {
49
+ text: 'six',
50
+ id: 6
51
+ }, {
52
+ text: 'seven',
53
+ id: 7
54
+ }, {
55
+ text: 'twenty',
56
+ id: 20
57
+ }, {
58
+ text: 'twentyone',
59
+ id: 21
60
+ }]; // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+
62
+ const AUTOCOMPLETE_LABEL = 'Autocomplete field';
63
+
64
+ const LabelledAutocomplete = ({
65
+ inputProps = {},
66
+ menuProps
67
+ }) => {
68
+ const {
69
+ ['aria-labelledby']: ariaLabelledBy = 'autocompleteLabel',
70
+ ...menuPropsRest
71
+ } = menuProps;
72
+ const {
73
+ id = 'autocompleteInput',
74
+ ...inputPropsRest
75
+ } = inputProps;
76
+ return /*#__PURE__*/_react.default.createElement(_ThemeProvider.ThemeProvider, {
77
+ theme: _theme.default
78
+ }, /*#__PURE__*/_react.default.createElement(_index.SSRProvider, null, /*#__PURE__*/_react.default.createElement(_BaseStyles.default, null, /*#__PURE__*/_react.default.createElement("label", {
79
+ htmlFor: id,
80
+ id: ariaLabelledBy
81
+ }, "Autocomplete field"), /*#__PURE__*/_react.default.createElement(_Autocomplete.default, {
82
+ id: "autocompleteId"
83
+ }, /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Input, _extends({
84
+ id: id
85
+ }, inputPropsRest)), /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Overlay, null, /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Menu, _extends({
86
+ "aria-labelledby": ariaLabelledBy
87
+ }, menuPropsRest)))))));
88
+ };
89
+
90
+ LabelledAutocomplete.displayName = "LabelledAutocomplete";
91
+ describe('Autocomplete', () => {
92
+ describe('snapshots', () => {
93
+ it('renders a single select input', () => {
94
+ expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_index.SSRProvider, null, /*#__PURE__*/_react.default.createElement(_Autocomplete.default, {
95
+ id: "autocompleteId"
96
+ }, /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Input, null), /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Menu, {
97
+ "aria-labelledby": "labelId",
98
+ items: mockItems,
99
+ selectedItemIds: []
100
+ }))))).toMatchSnapshot();
101
+ });
102
+ it('renders a multiselect input', () => {
103
+ expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_index.SSRProvider, null, /*#__PURE__*/_react.default.createElement(_Autocomplete.default, {
104
+ id: "autocompleteId"
105
+ }, /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Input, null), /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Menu, {
106
+ "aria-labelledby": "labelId",
107
+ items: mockItems,
108
+ selectedItemIds: [],
109
+ selectionVariant: "multiple"
110
+ }))))).toMatchSnapshot();
111
+ });
112
+ it('renders a multiselect input with selected menu items', () => {
113
+ expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_index.SSRProvider, null, /*#__PURE__*/_react.default.createElement(_Autocomplete.default, {
114
+ id: "autocompleteId"
115
+ }, /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Input, null), /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Menu, {
116
+ "aria-labelledby": "labelId",
117
+ items: mockItems,
118
+ selectedItemIds: [0, 1, 2],
119
+ selectionVariant: "multiple"
120
+ }))))).toMatchSnapshot();
121
+ });
122
+ it('renders a menu that contains an item to add to the menu', () => {
123
+ const handleAddItemMock = jest.fn();
124
+ expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_index.SSRProvider, null, /*#__PURE__*/_react.default.createElement(_Autocomplete.default, {
125
+ id: "autocompleteId"
126
+ }, /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Input, null), /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Menu, {
127
+ "aria-labelledby": "labelId",
128
+ items: mockItems,
129
+ selectionVariant: "multiple",
130
+ selectedItemIds: [],
131
+ addNewItem: {
132
+ text: 'Add new item',
133
+ handleAddItem: handleAddItemMock
134
+ }
135
+ }))))).toMatchSnapshot();
136
+ });
137
+ it('renders a custom empty state message', () => {
138
+ expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_index.SSRProvider, null, /*#__PURE__*/_react.default.createElement(_Autocomplete.default, {
139
+ id: "autocompleteId"
140
+ }, /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Input, null), /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Menu, {
141
+ "aria-labelledby": "labelId",
142
+ items: [],
143
+ selectedItemIds: [],
144
+ emptyStateText: "No results"
145
+ }))))).toMatchSnapshot();
146
+ });
147
+ it('renders a loading state', () => {
148
+ expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_index.SSRProvider, null, /*#__PURE__*/_react.default.createElement(_Autocomplete.default, {
149
+ id: "autocompleteId"
150
+ }, /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Input, null), /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Menu, {
151
+ "aria-labelledby": "labelId",
152
+ loading: true,
153
+ items: [],
154
+ selectedItemIds: []
155
+ }))))).toMatchSnapshot();
156
+ });
157
+ it('renders with a custom text input component', () => {
158
+ expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_index.SSRProvider, null, /*#__PURE__*/_react.default.createElement(_Autocomplete.default, {
159
+ id: "autocompleteId"
160
+ }, /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Input, {
161
+ as: () => /*#__PURE__*/_react.default.createElement("input", {
162
+ type: "text",
163
+ id: "customInput"
164
+ })
165
+ }), /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Menu, {
166
+ "aria-labelledby": "labelId",
167
+ items: mockItems,
168
+ selectedItemIds: []
169
+ }))))).toMatchSnapshot();
170
+ });
171
+ it('renders with an input value', () => {
172
+ expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_index.SSRProvider, null, /*#__PURE__*/_react.default.createElement(_Autocomplete.default, {
173
+ id: "autocompleteId"
174
+ }, /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Input, {
175
+ value: "test"
176
+ }), /*#__PURE__*/_react.default.createElement(_Autocomplete.default.Menu, {
177
+ "aria-labelledby": "labelId",
178
+ items: mockItems,
179
+ selectedItemIds: []
180
+ }))))).toMatchSnapshot();
181
+ });
182
+ });
183
+ describe('Autocomplete.Input', () => {
184
+ it('calls onChange', () => {
185
+ const onChangeMock = jest.fn();
186
+ const {
187
+ container
188
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
189
+ inputProps: {
190
+ onChange: onChangeMock
191
+ },
192
+ menuProps: {
193
+ items: mockItems,
194
+ selectedItemIds: []
195
+ }
196
+ }));
197
+ const inputNode = container.querySelector('#autocompleteInput');
198
+ expect(onChangeMock).not.toHaveBeenCalled();
199
+ inputNode && _userEvent.default.type(inputNode, 'z');
200
+ expect(onChangeMock).toHaveBeenCalled();
201
+ });
202
+ it('calls onFocus', () => {
203
+ const onFocusMock = jest.fn();
204
+ const {
205
+ container
206
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
207
+ inputProps: {
208
+ onFocus: onFocusMock
209
+ },
210
+ menuProps: {
211
+ items: mockItems,
212
+ selectedItemIds: []
213
+ }
214
+ }));
215
+ const inputNode = container.querySelector('#autocompleteInput');
216
+ expect(onFocusMock).not.toHaveBeenCalled();
217
+ inputNode && _react2.fireEvent.focus(inputNode);
218
+ expect(onFocusMock).toHaveBeenCalled();
219
+ });
220
+ it('calls onKeyDown', () => {
221
+ const onKeyDownMock = jest.fn();
222
+ const {
223
+ getByLabelText
224
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
225
+ inputProps: {
226
+ onKeyDown: onKeyDownMock
227
+ },
228
+ menuProps: {
229
+ items: [],
230
+ selectedItemIds: []
231
+ }
232
+ }));
233
+ const inputNode = getByLabelText(AUTOCOMPLETE_LABEL);
234
+ expect(onKeyDownMock).not.toHaveBeenCalled();
235
+
236
+ _react2.fireEvent.keyDown(inputNode, {
237
+ key: 'Shift'
238
+ });
239
+
240
+ expect(onKeyDownMock).toHaveBeenCalled();
241
+ });
242
+ it('calls onKeyUp', () => {
243
+ const onKeyUpMock = jest.fn();
244
+ const {
245
+ getByLabelText
246
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
247
+ inputProps: {
248
+ onKeyUp: onKeyUpMock
249
+ },
250
+ menuProps: {
251
+ items: [],
252
+ selectedItemIds: []
253
+ }
254
+ }));
255
+ const inputNode = getByLabelText(AUTOCOMPLETE_LABEL);
256
+ expect(onKeyUpMock).not.toHaveBeenCalled();
257
+
258
+ _react2.fireEvent.keyUp(inputNode, {
259
+ key: 'Shift'
260
+ });
261
+
262
+ expect(onKeyUpMock).toHaveBeenCalled();
263
+ });
264
+ it('calls onKeyPress', () => {
265
+ const onKeyPressMock = jest.fn();
266
+ const {
267
+ getByLabelText
268
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
269
+ inputProps: {
270
+ onKeyPress: onKeyPressMock
271
+ },
272
+ menuProps: {
273
+ items: [],
274
+ selectedItemIds: []
275
+ }
276
+ }));
277
+ const inputNode = getByLabelText(AUTOCOMPLETE_LABEL);
278
+ expect(onKeyPressMock).not.toHaveBeenCalled();
279
+
280
+ _userEvent.default.type(inputNode, '{enter}');
281
+
282
+ expect(onKeyPressMock).toHaveBeenCalled();
283
+ });
284
+ it('opens the menu when the input is focused', () => {
285
+ const {
286
+ getByLabelText
287
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
288
+ menuProps: {
289
+ items: [],
290
+ selectedItemIds: []
291
+ }
292
+ }));
293
+ const inputNode = getByLabelText(AUTOCOMPLETE_LABEL);
294
+ expect(inputNode.getAttribute('aria-expanded')).not.toBe('true');
295
+
296
+ _react2.fireEvent.focus(inputNode);
297
+
298
+ expect(inputNode.getAttribute('aria-expanded')).toBe('true');
299
+ });
300
+ it('closes the menu when the input is blurred', () => {
301
+ const {
302
+ getByLabelText
303
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
304
+ menuProps: {
305
+ items: [],
306
+ selectedItemIds: []
307
+ }
308
+ }));
309
+ const inputNode = getByLabelText(AUTOCOMPLETE_LABEL);
310
+ expect(inputNode.getAttribute('aria-expanded')).not.toBe('true');
311
+
312
+ _react2.fireEvent.focus(inputNode);
313
+
314
+ expect(inputNode.getAttribute('aria-expanded')).toBe('true'); // eslint-disable-next-line github/no-blur
315
+
316
+ _react2.fireEvent.blur(inputNode); // wait a tick for blur to finish
317
+
318
+
319
+ setTimeout(() => {
320
+ expect(inputNode.getAttribute('aria-expanded')).not.toBe('true');
321
+ }, 0);
322
+ });
323
+ it('sets the input value to the suggested item text and highlights the untyped part of the word', () => {
324
+ const {
325
+ container,
326
+ getByDisplayValue
327
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
328
+ menuProps: {
329
+ items: mockItems,
330
+ selectedItemIds: []
331
+ }
332
+ }));
333
+ const inputNode = container.querySelector('#autocompleteInput');
334
+ inputNode && _userEvent.default.type(inputNode, 'ze');
335
+ expect(getByDisplayValue('zero')).toBeDefined();
336
+ });
337
+ it('does not show or highlight suggestion text after the user hits Backspace until they hit another key', () => {
338
+ const {
339
+ container,
340
+ getByDisplayValue
341
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
342
+ menuProps: {
343
+ items: mockItems,
344
+ selectedItemIds: []
345
+ }
346
+ }));
347
+ const inputNode = container.querySelector('#autocompleteInput');
348
+ expect(inputNode.selectionStart).toBe(0);
349
+ inputNode && _userEvent.default.type(inputNode, 'ze');
350
+ expect(getByDisplayValue('zero')).toBeDefined();
351
+ expect(inputNode.selectionStart).toBe(2);
352
+ expect(inputNode.selectionEnd).toBe(4);
353
+ inputNode && _userEvent.default.type(inputNode, '{backspace}');
354
+ expect(inputNode.selectionStart).toBe(2);
355
+ expect(getByDisplayValue('ze')).toBeDefined();
356
+ inputNode && _userEvent.default.type(inputNode, 'r');
357
+ expect(inputNode.selectionStart).toBe(3);
358
+ expect(inputNode.selectionEnd).toBe(4);
359
+ expect(getByDisplayValue('zero')).toBeDefined();
360
+ });
361
+ it('clears the input value when when the user hits Escape', () => {
362
+ const {
363
+ container
364
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
365
+ menuProps: {
366
+ items: mockItems,
367
+ selectedItemIds: []
368
+ }
369
+ }));
370
+ const inputNode = container.querySelector('#autocompleteInput');
371
+ expect(inputNode === null || inputNode === void 0 ? void 0 : inputNode.getAttribute('aria-expanded')).not.toBe('true');
372
+ inputNode && _userEvent.default.type(inputNode, 'ze');
373
+ expect(inputNode === null || inputNode === void 0 ? void 0 : inputNode.getAttribute('aria-expanded')).toBe('true');
374
+ inputNode && _userEvent.default.type(inputNode, '{esc}');
375
+ expect(inputNode === null || inputNode === void 0 ? void 0 : inputNode.getAttribute('aria-expanded')).not.toBe('true');
376
+ });
377
+ });
378
+ describe('Autocomplete.Menu', () => {
379
+ it('calls a custom filter function', () => {
380
+ const filterFnMock = jest.fn();
381
+ const {
382
+ container
383
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
384
+ menuProps: {
385
+ items: mockItems,
386
+ selectedItemIds: [],
387
+ filterFn: filterFnMock
388
+ }
389
+ }));
390
+ const inputNode = container.querySelector('#autocompleteInput');
391
+ inputNode && _userEvent.default.type(inputNode, 'ze');
392
+ expect(filterFnMock).toHaveBeenCalled();
393
+ });
394
+ it('calls a custom sort function when the menu closes', () => {
395
+ const sortOnCloseFnMock = jest.fn();
396
+ const {
397
+ container
398
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
399
+ menuProps: {
400
+ items: mockItems,
401
+ selectedItemIds: [],
402
+ sortOnCloseFn: sortOnCloseFnMock
403
+ }
404
+ }));
405
+ const inputNode = container.querySelector('#autocompleteInput'); // `sortOnCloseFnMock` will be called in a `.sort()` on render to check if the
406
+ // current sort order matches the result of `sortOnCloseFnMock`
407
+
408
+ expect(sortOnCloseFnMock).toHaveBeenCalledTimes(mockItems.length - 1);
409
+
410
+ if (inputNode) {
411
+ _userEvent.default.type(inputNode, 'ze'); // eslint-disable-next-line github/no-blur
412
+
413
+
414
+ _react2.fireEvent.blur(inputNode);
415
+ } // wait a tick for blur to finish
416
+
417
+
418
+ setTimeout(() => {
419
+ expect(sortOnCloseFnMock).toHaveBeenCalledTimes(mockItems.length);
420
+ }, 0);
421
+ });
422
+ it("calls onOpenChange with the menu's open state", () => {
423
+ const onOpenChangeMock = jest.fn();
424
+ const {
425
+ container
426
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
427
+ menuProps: {
428
+ items: mockItems,
429
+ selectedItemIds: [],
430
+ onOpenChange: onOpenChangeMock
431
+ }
432
+ }));
433
+ const inputNode = container.querySelector('#autocompleteInput');
434
+ inputNode && _userEvent.default.type(inputNode, 'ze');
435
+ expect(onOpenChangeMock).toHaveBeenCalled();
436
+ });
437
+ it('calls onSelectedChange with the data for the selected items', () => {
438
+ const onSelectedChangeMock = jest.fn();
439
+ const {
440
+ container
441
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
442
+ menuProps: {
443
+ items: mockItems,
444
+ selectedItemIds: [],
445
+ onSelectedChange: onSelectedChangeMock
446
+ }
447
+ }));
448
+ const inputNode = container.querySelector('#autocompleteInput');
449
+ expect(onSelectedChangeMock).not.toHaveBeenCalled();
450
+
451
+ if (inputNode) {
452
+ _react2.fireEvent.focus(inputNode);
453
+
454
+ _userEvent.default.type(inputNode, '{enter}');
455
+ } // wait a tick for the keyboard event to be dispatched to the menu item
456
+
457
+
458
+ setTimeout(() => {
459
+ expect(onSelectedChangeMock).toHaveBeenCalledWith([mockItems[0]]);
460
+ }, 0);
461
+ });
462
+ it('does not close the menu when clicking an item in the menu if selectionVariant=multiple', () => {
463
+ const {
464
+ getByText,
465
+ container
466
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
467
+ menuProps: {
468
+ items: mockItems,
469
+ selectedItemIds: [],
470
+ selectionVariant: 'multiple'
471
+ }
472
+ }));
473
+ const inputNode = container.querySelector('#autocompleteInput');
474
+ const itemToClickNode = getByText(mockItems[1].text);
475
+ expect(inputNode === null || inputNode === void 0 ? void 0 : inputNode.getAttribute('aria-expanded')).not.toBe('true');
476
+ inputNode && _react2.fireEvent.focus(inputNode);
477
+ expect(inputNode === null || inputNode === void 0 ? void 0 : inputNode.getAttribute('aria-expanded')).toBe('true');
478
+
479
+ _react2.fireEvent.click(itemToClickNode);
480
+
481
+ inputNode && _userEvent.default.type(inputNode, '{enter}');
482
+ expect(inputNode === null || inputNode === void 0 ? void 0 : inputNode.getAttribute('aria-expanded')).toBe('true');
483
+ });
484
+ it('closes the menu when clicking an item in the menu if selectionVariant=single', () => {
485
+ const {
486
+ getByText,
487
+ container
488
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
489
+ menuProps: {
490
+ items: mockItems,
491
+ selectedItemIds: [],
492
+ selectionVariant: 'single'
493
+ }
494
+ }));
495
+ const inputNode = container.querySelector('#autocompleteInput');
496
+ const itemToClickNode = getByText(mockItems[1].text);
497
+ expect(inputNode === null || inputNode === void 0 ? void 0 : inputNode.getAttribute('aria-expanded')).not.toBe('true');
498
+ inputNode && _react2.fireEvent.focus(inputNode);
499
+ expect(inputNode === null || inputNode === void 0 ? void 0 : inputNode.getAttribute('aria-expanded')).toBe('true');
500
+
501
+ _react2.fireEvent.click(itemToClickNode);
502
+
503
+ expect(inputNode === null || inputNode === void 0 ? void 0 : inputNode.getAttribute('aria-expanded')).not.toBe('true');
504
+ });
505
+ it('calls handleAddItem with new item data when passing addNewItem', () => {
506
+ const handleAddItemMock = jest.fn();
507
+ const {
508
+ getByText
509
+ } = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(LabelledAutocomplete, {
510
+ menuProps: {
511
+ items: mockItems,
512
+ selectedItemIds: [],
513
+ selectionVariant: 'multiple',
514
+ addNewItem: {
515
+ text: 'Add new item',
516
+ handleAddItem: handleAddItemMock
517
+ }
518
+ }
519
+ }));
520
+ const addNewItemNode = getByText('Add new item');
521
+ expect(handleAddItemMock).not.toHaveBeenCalled();
522
+
523
+ _react2.fireEvent.click(addNewItemNode);
524
+
525
+ expect(handleAddItemMock).toHaveBeenCalled();
526
+ });
527
+ });
528
+ });
@@ -37,7 +37,7 @@ describe('BorderBox', () => {
37
37
 
38
38
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.BorderBox, {
39
39
  borderColor: "success.emphasis"
40
- }))).toHaveStyleRule('border-color', (_theme$colorSchemes$l = _theme.default.colorSchemes.light.colors.border) === null || _theme$colorSchemes$l === void 0 ? void 0 : _theme$colorSchemes$l.success);
40
+ }))).toHaveStyleRule('border-color', (_theme$colorSchemes$l = _theme.default.colorSchemes.light.colors.success) === null || _theme$colorSchemes$l === void 0 ? void 0 : _theme$colorSchemes$l.emphasis);
41
41
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.BorderBox, {
42
42
  borderBottom: 0
43
43
  }))).toHaveStyleRule('border-bottom', '0');
@@ -59,7 +59,7 @@ describe('CircleOcticon', () => {
59
59
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.CircleOcticon, {
60
60
  icon: _octiconsReact.CheckIcon,
61
61
  bg: "danger.subtle"
62
- }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l = _theme.default.colorSchemes.light.colors.bg) === null || _theme$colorSchemes$l === void 0 ? void 0 : _theme$colorSchemes$l.danger);
62
+ }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l = _theme.default.colorSchemes.light.colors.danger) === null || _theme$colorSchemes$l === void 0 ? void 0 : _theme$colorSchemes$l.subtle);
63
63
  });
64
64
  it('has a default size', () => {
65
65
  const result = (0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.CircleOcticon, {
@@ -40,19 +40,19 @@ describe('CounterLabel', () => {
40
40
 
41
41
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.CounterLabel, {
42
42
  scheme: "primary"
43
- }))).toHaveStyleRule('color', (_theme$colorSchemes$l = _theme.default.colorSchemes.light.colors.counter) === null || _theme$colorSchemes$l === void 0 ? void 0 : _theme$colorSchemes$l.primary.text.trim());
43
+ }))).toHaveStyleRule('color', (_theme$colorSchemes$l = _theme.default.colorSchemes.light.colors.fg) === null || _theme$colorSchemes$l === void 0 ? void 0 : _theme$colorSchemes$l.onEmphasis.trim());
44
44
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.CounterLabel, {
45
45
  scheme: "primary"
46
- }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l2 = _theme.default.colorSchemes.light.colors.counter) === null || _theme$colorSchemes$l2 === void 0 ? void 0 : _theme$colorSchemes$l2.primary.bg.trim());
46
+ }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l2 = _theme.default.colorSchemes.light.colors.neutral) === null || _theme$colorSchemes$l2 === void 0 ? void 0 : _theme$colorSchemes$l2.emphasis.trim());
47
47
  });
48
48
  it('respects the secondary "scheme" prop', () => {
49
49
  var _theme$colorSchemes$l3, _theme$colorSchemes$l4;
50
50
 
51
51
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.CounterLabel, {
52
52
  scheme: "secondary"
53
- }))).toHaveStyleRule('color', (_theme$colorSchemes$l3 = _theme.default.colorSchemes.light.colors.counter) === null || _theme$colorSchemes$l3 === void 0 ? void 0 : _theme$colorSchemes$l3.text.trim());
53
+ }))).toHaveStyleRule('color', (_theme$colorSchemes$l3 = _theme.default.colorSchemes.light.colors.fg) === null || _theme$colorSchemes$l3 === void 0 ? void 0 : _theme$colorSchemes$l3.default.trim());
54
54
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.CounterLabel, {
55
55
  scheme: "secondary"
56
- }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l4 = _theme.default.colorSchemes.light.colors.counter) === null || _theme$colorSchemes$l4 === void 0 ? void 0 : _theme$colorSchemes$l4.bg);
56
+ }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l4 = _theme.default.colorSchemes.light.colors.neutral) === null || _theme$colorSchemes$l4 === void 0 ? void 0 : _theme$colorSchemes$l4.muted);
57
57
  });
58
58
  });
@@ -50,13 +50,13 @@ describe('Flash', () => {
50
50
 
51
51
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.Flash, {
52
52
  variant: "warning"
53
- }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l = _theme.default.colorSchemes.light.colors.alert) === null || _theme$colorSchemes$l === void 0 ? void 0 : _theme$colorSchemes$l.warn.bg);
53
+ }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l = _theme.default.colorSchemes.light.colors.attention) === null || _theme$colorSchemes$l === void 0 ? void 0 : _theme$colorSchemes$l.subtle);
54
54
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.Flash, {
55
55
  variant: "danger"
56
- }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l2 = _theme.default.colorSchemes.light.colors.alert) === null || _theme$colorSchemes$l2 === void 0 ? void 0 : _theme$colorSchemes$l2.error.bg);
56
+ }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l2 = _theme.default.colorSchemes.light.colors.danger) === null || _theme$colorSchemes$l2 === void 0 ? void 0 : _theme$colorSchemes$l2.subtle);
57
57
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.Flash, {
58
58
  variant: "success"
59
- }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l3 = _theme.default.colorSchemes.light.colors.alert) === null || _theme$colorSchemes$l3 === void 0 ? void 0 : _theme$colorSchemes$l3.success.bg);
60
- expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.Flash, null))).toHaveStyleRule('background-color', (_theme$colorSchemes$l4 = _theme.default.colorSchemes.light.colors.alert) === null || _theme$colorSchemes$l4 === void 0 ? void 0 : _theme$colorSchemes$l4.info.bg);
59
+ }))).toHaveStyleRule('background-color', (_theme$colorSchemes$l3 = _theme.default.colorSchemes.light.colors.success) === null || _theme$colorSchemes$l3 === void 0 ? void 0 : _theme$colorSchemes$l3.subtle);
60
+ expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.Flash, null))).toHaveStyleRule('background-color', (_theme$colorSchemes$l4 = _theme.default.colorSchemes.light.colors.accent) === null || _theme$colorSchemes$l4 === void 0 ? void 0 : _theme$colorSchemes$l4.subtle);
61
61
  });
62
62
  });
@@ -39,7 +39,7 @@ describe('Link', () => {
39
39
  });
40
40
  it('respects hoverColor prop', () => {
41
41
  expect((0, _testing.render)( /*#__PURE__*/_react.default.createElement(_.Link, {
42
- hoverColor: "text.link"
42
+ hoverColor: "accent.fg"
43
43
  }))).toMatchSnapshot();
44
44
  });
45
45
  it('respects the "fontStyle" prop', () => {