@primer/components 31.0.2-rc.1e80de40 → 31.0.2-rc.95622264

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.
@@ -45,6 +45,7 @@ const TextInputWrapper = styled.span<StyledWrapperProps>`
45
45
  border-radius: ${get('radii.2')};
46
46
  outline: none;
47
47
  box-shadow: ${get('shadows.primer.shadow.inset')};
48
+ cursor: text;
48
49
 
49
50
  ${props => {
50
51
  if (props.hasIcon) {
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
  import {render} from '../utils/testing'
3
- import {render as HTMLRender, cleanup, fireEvent} from '@testing-library/react'
3
+ import {render as HTMLRender, fireEvent, act, cleanup} from '@testing-library/react'
4
4
  import {axe, toHaveNoViolations} from 'jest-axe'
5
5
  import 'babel-polyfill'
6
6
  import {TokenSizeKeys, tokenSizes} from '../Token/TokenBase'
@@ -29,6 +29,18 @@ const LabelledTextInputWithTokens: React.FC<TextInputWithTokensProps> = ({onToke
29
29
  </>
30
30
  )
31
31
 
32
+ // describe('axe test', () => {
33
+ // it('should have no axe violations', async () => {
34
+ // const onRemoveMock = jest.fn()
35
+ // const {container} = HTMLRender(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock} />)
36
+ // const results = await axe(container)
37
+ // expect(results).toHaveNoViolations()
38
+ // cleanup()
39
+ // })
40
+ // })
41
+
42
+ jest.useFakeTimers()
43
+
32
44
  describe('TextInputWithTokens', () => {
33
45
  it('renders without tokens', () => {
34
46
  const onRemoveMock = jest.fn()
@@ -85,6 +97,13 @@ describe('TextInputWithTokens', () => {
85
97
  ).toMatchSnapshot()
86
98
  })
87
99
 
100
+ it('renders a truncated set of tokens', () => {
101
+ const onRemoveMock = jest.fn()
102
+ expect(
103
+ render(<TextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock} visibleTokenCount={2} />)
104
+ ).toMatchSnapshot()
105
+ })
106
+
88
107
  it('focuses the previous token when keying ArrowLeft', () => {
89
108
  const onRemoveMock = jest.fn()
90
109
  const {getByLabelText, getByText} = HTMLRender(
@@ -165,6 +184,119 @@ describe('TextInputWithTokens', () => {
165
184
  expect(document.activeElement?.id).toEqual(inputNode.id)
166
185
  })
167
186
 
187
+ it('does not focus the input when clicking a token', () => {
188
+ const onRemoveMock = jest.fn()
189
+ const {getByLabelText, getByText} = HTMLRender(
190
+ <LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock} visibleTokenCount={2} />
191
+ )
192
+ const inputNode = getByLabelText('Tokens')
193
+ const tokenNode = getByText(mockTokens[0].text)
194
+
195
+ expect(document.activeElement).not.toEqual(inputNode.id)
196
+ fireEvent.click(tokenNode)
197
+ expect(document.activeElement?.id).not.toEqual(inputNode.id)
198
+ })
199
+
200
+ it('focuses the input when clicking somewhere in the component besides the tokens', () => {
201
+ const onRemoveMock = jest.fn()
202
+ const {getByLabelText, getByText} = HTMLRender(
203
+ <LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock} visibleTokenCount={2} />
204
+ )
205
+ const inputNode = getByLabelText('Tokens')
206
+ const truncatedTokenCount = getByText('+6')
207
+
208
+ expect(document.activeElement).not.toEqual(inputNode.id)
209
+ fireEvent.click(truncatedTokenCount)
210
+ expect(document.activeElement?.id).toEqual(inputNode.id)
211
+ })
212
+
213
+ it('shows all tokens when the input is focused and hides them when it is blurred (when visibleTokenCount is set)', () => {
214
+ const onRemoveMock = jest.fn()
215
+ const visibleTokenCount = 2
216
+ const {getByLabelText, getByText} = HTMLRender(
217
+ <>
218
+ <LabelledTextInputWithTokens
219
+ tokens={mockTokens}
220
+ onTokenRemove={onRemoveMock}
221
+ visibleTokenCount={visibleTokenCount}
222
+ />
223
+ <button id="focusableOutsideComponent">Focus me</button>
224
+ </>
225
+ )
226
+ const inputNode = getByLabelText('Tokens')
227
+ const focusableOutsideComponentNode = getByText('Focus me')
228
+ const allTokenLabels = mockTokens.map(token => token.text)
229
+ const truncatedTokenCountNode = getByText('+6')
230
+
231
+ act(() => {
232
+ jest.runAllTimers()
233
+ fireEvent.focus(inputNode)
234
+ })
235
+
236
+ setTimeout(() => {
237
+ for (const tokenLabel of allTokenLabels) {
238
+ const tokenNode = getByText(tokenLabel)
239
+ expect(tokenNode).toBeDefined()
240
+ }
241
+ }, 0)
242
+
243
+ act(() => {
244
+ jest.runAllTimers()
245
+ // onBlur isn't called on input unless we specifically fire the "blur" event
246
+ // eslint-disable-next-line github/no-blur
247
+ fireEvent.blur(inputNode)
248
+ fireEvent.focus(focusableOutsideComponentNode)
249
+ })
250
+
251
+ setTimeout(() => {
252
+ expect(truncatedTokenCountNode).toBeDefined()
253
+
254
+ for (const tokenLabel of allTokenLabels) {
255
+ const tokenNode = getByText(tokenLabel)
256
+ if (allTokenLabels.indexOf(tokenLabel) > visibleTokenCount) {
257
+ // eslint-disable-next-line jest/no-conditional-expect
258
+ expect(tokenNode).toBeDefined()
259
+ } else {
260
+ // eslint-disable-next-line jest/no-conditional-expect
261
+ expect(tokenNode).not.toBeDefined()
262
+ }
263
+ }
264
+ }, 0)
265
+
266
+ jest.useRealTimers()
267
+ })
268
+
269
+ it('does not hide tokens when blurring the input to focus within the component (when visibleTokenCount is set)', () => {
270
+ const onRemoveMock = jest.fn()
271
+ const visibleTokenCount = 2
272
+ const {getByLabelText, getByText} = HTMLRender(
273
+ <>
274
+ <LabelledTextInputWithTokens
275
+ tokens={mockTokens}
276
+ onTokenRemove={onRemoveMock}
277
+ visibleTokenCount={visibleTokenCount}
278
+ />
279
+ <button id="focusableOutsideComponent">Focus me</button>
280
+ </>
281
+ )
282
+ const inputNode = getByLabelText('Tokens')
283
+ const firstTokenNode = getByText(mockTokens[visibleTokenCount - 1].text)
284
+ const allTokenLabels = mockTokens.map(token => token.text)
285
+ const truncatedTokenCountNode = getByText('+6')
286
+
287
+ act(() => {
288
+ fireEvent.focus(inputNode)
289
+ fireEvent.focus(firstTokenNode)
290
+ })
291
+
292
+ expect(truncatedTokenCountNode).toBeDefined()
293
+
294
+ for (const tokenLabel of allTokenLabels) {
295
+ const tokenNode = getByText(tokenLabel)
296
+ expect(tokenNode).toBeDefined()
297
+ }
298
+ })
299
+
168
300
  it('focuses the first token when keying ArrowRight in the input', () => {
169
301
  const onRemoveMock = jest.fn()
170
302
  const {getByLabelText, getByText} = HTMLRender(
@@ -238,6 +370,44 @@ describe('TextInputWithTokens', () => {
238
370
  expect(onRemoveMock).toHaveBeenCalledWith(mockTokens[4].id)
239
371
  })
240
372
 
373
+ it('moves focus to the next token when removing the first token', () => {
374
+ jest.useFakeTimers()
375
+ const onRemoveMock = jest.fn()
376
+ const {getByText} = HTMLRender(
377
+ <TextInputWithTokens tokens={[...mockTokens].slice(0, 2)} onTokenRemove={onRemoveMock} />
378
+ )
379
+ const tokenNode = getByText(mockTokens[0].text)
380
+
381
+ fireEvent.focus(tokenNode)
382
+ fireEvent.keyDown(tokenNode, {key: 'Backspace'})
383
+
384
+ jest.runAllTimers()
385
+ setTimeout(() => {
386
+ expect(document.activeElement?.textContent).toBe(mockTokens[1].text)
387
+ }, 0)
388
+
389
+ jest.useRealTimers()
390
+ })
391
+
392
+ it('moves focus to the input when the last token is removed', () => {
393
+ jest.useFakeTimers()
394
+ const onRemoveMock = jest.fn()
395
+ const {getByText, getByLabelText} = HTMLRender(
396
+ <LabelledTextInputWithTokens tokens={[mockTokens[0]]} onTokenRemove={onRemoveMock} />
397
+ )
398
+ const tokenNode = getByText(mockTokens[0].text)
399
+ const inputNode = getByLabelText('Tokens')
400
+
401
+ fireEvent.focus(tokenNode)
402
+ fireEvent.keyDown(tokenNode, {key: 'Backspace'})
403
+
404
+ jest.runAllTimers()
405
+ setTimeout(() => {
406
+ expect(document.activeElement?.id).toBe(inputNode.id)
407
+ }, 0)
408
+ jest.useRealTimers()
409
+ })
410
+
241
411
  it('calls onKeyDown', () => {
242
412
  const onRemoveMock = jest.fn()
243
413
  const onKeyDownMock = jest.fn()
@@ -36,6 +36,7 @@ Array [
36
36
  border-radius: 6px;
37
37
  outline: none;
38
38
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
39
+ cursor: text;
39
40
  padding: 6px 12px;
40
41
  }
41
42
 
@@ -148,6 +149,7 @@ Array [
148
149
  border-radius: 6px;
149
150
  outline: none;
150
151
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
152
+ cursor: text;
151
153
  padding: 6px 12px;
152
154
  }
153
155
 
@@ -295,6 +297,7 @@ Array [
295
297
  border-radius: 6px;
296
298
  outline: none;
297
299
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
300
+ cursor: text;
298
301
  padding: 6px 12px;
299
302
  }
300
303
 
@@ -1040,6 +1043,7 @@ Array [
1040
1043
  border-radius: 6px;
1041
1044
  outline: none;
1042
1045
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
1046
+ cursor: text;
1043
1047
  padding: 6px 12px;
1044
1048
  }
1045
1049
 
@@ -1708,6 +1712,7 @@ Array [
1708
1712
  border-radius: 6px;
1709
1713
  outline: none;
1710
1714
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
1715
+ cursor: text;
1711
1716
  padding: 6px 12px;
1712
1717
  }
1713
1718
 
@@ -2376,6 +2381,7 @@ Array [
2376
2381
  border-radius: 6px;
2377
2382
  outline: none;
2378
2383
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
2384
+ cursor: text;
2379
2385
  padding: 6px 12px;
2380
2386
  }
2381
2387
 
@@ -3337,6 +3343,7 @@ Array [
3337
3343
  border-radius: 6px;
3338
3344
  outline: none;
3339
3345
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
3346
+ cursor: text;
3340
3347
  padding: 6px 12px;
3341
3348
  }
3342
3349
 
@@ -35,6 +35,7 @@ exports[`TextInput renders 1`] = `
35
35
  border-radius: 6px;
36
36
  outline: none;
37
37
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
38
+ cursor: text;
38
39
  padding: 6px 12px;
39
40
  }
40
41
 
@@ -106,6 +107,7 @@ exports[`TextInput renders block 1`] = `
106
107
  border-radius: 6px;
107
108
  outline: none;
108
109
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
110
+ cursor: text;
109
111
  padding: 6px 12px;
110
112
  display: block;
111
113
  width: 100%;
@@ -179,6 +181,7 @@ exports[`TextInput renders consistently 1`] = `
179
181
  border-radius: 6px;
180
182
  outline: none;
181
183
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
184
+ cursor: text;
182
185
  padding: 6px 12px;
183
186
  }
184
187
 
@@ -249,6 +252,7 @@ exports[`TextInput renders large 1`] = `
249
252
  border-radius: 6px;
250
253
  outline: none;
251
254
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
255
+ cursor: text;
252
256
  padding: 6px 12px;
253
257
  padding-left: 8px;
254
258
  padding-right: 8px;
@@ -325,6 +329,7 @@ exports[`TextInput renders small 1`] = `
325
329
  border-radius: 6px;
326
330
  outline: none;
327
331
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
332
+ cursor: text;
328
333
  padding: 6px 12px;
329
334
  min-height: 28px;
330
335
  padding-left: 8px;
@@ -403,6 +408,7 @@ exports[`TextInput should render a password input 1`] = `
403
408
  border-radius: 6px;
404
409
  outline: none;
405
410
  box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
411
+ cursor: text;
406
412
  padding: 6px 12px;
407
413
  }
408
414