learningtribes-studio-frontend 1.4.2-alpha.3 → 1.4.2-alpha.5
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/dist/accessibilityPolicy.min.js +2 -2
- package/dist/assets.min.css +1 -1
- package/dist/assets.min.js +1 -1
- package/dist/assets.min.js.map +1 -1
- package/dist/common.min.css +2 -2
- package/dist/common.min.js +7 -7
- package/dist/common.min.js.map +1 -1
- package/dist/courseHealthCheck.min.js +1 -1
- package/dist/courseOutlineHealthCheck.min.js +1 -1
- package/dist/editImageModal.min.css +1 -1
- package/dist/editImageModal.min.js +1 -1
- package/dist/editImageModal.min.js.map +1 -1
- package/dist/i18nMessages.min.js +1 -1
- package/dist/i18nMessages.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AssetsDropZone/AssetsDropZone.scss +110 -76
- package/src/components/AssetsDropZone/AssetsDropZone.test.jsx +3 -1
- package/src/components/AssetsDropZone/displayMessages.jsx +12 -2
- package/src/components/AssetsDropZone/index.jsx +176 -88
- package/src/components/AssetsList/AssetsList.scss +2 -2
- package/src/components/AssetsList/AssetsList.test.jsx +125 -145
- package/src/components/AssetsList/index.jsx +20 -2
- package/src/components/EditImageModal/EditImageModal.scss +2 -0
- package/src/components/EditImageModal/EditImageModal.test.jsx +93 -228
- package/src/components/EditImageModal/displayMessages.jsx +1 -6
- package/src/components/EditImageModal/index.jsx +64 -208
- package/src/data/i18n/default/transifex_input.json +3 -2
|
@@ -2,10 +2,8 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import AssetsList from './index';
|
|
4
4
|
import { courseDetails, testAssetsList } from '../../utils/testConstants';
|
|
5
|
-
import
|
|
6
|
-
import { mountWithIntl } from '../../utils/i18n/enzymeHelper';
|
|
5
|
+
import { shallowWithIntl } from '../../utils/i18n/enzymeHelper';
|
|
7
6
|
import { paginationInitial, selectInitial } from '../../data/reducers/assets';
|
|
8
|
-
import WrappedMessage from '../../utils/i18n/formattedMessageWrapper';
|
|
9
7
|
|
|
10
8
|
const paginationMetadata = {
|
|
11
9
|
...paginationInitial,
|
|
@@ -22,24 +20,25 @@ const defaultProps = {
|
|
|
22
20
|
|
|
23
21
|
let items;
|
|
24
22
|
let list;
|
|
25
|
-
let wrapper =
|
|
23
|
+
let wrapper = shallowWithIntl(
|
|
26
24
|
<AssetsList
|
|
27
25
|
{...defaultProps}
|
|
28
26
|
/>);
|
|
29
27
|
|
|
30
28
|
const selectAssetSpy = jest.fn();
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
const mouseDown = node => node.simulate('mouseDown', { preventDefault() {} });
|
|
31
|
+
const keyDown = (node, key) => node.simulate('keyDown', { key, preventDefault() {} });
|
|
32
|
+
|
|
33
33
|
const updateConstants = () => {
|
|
34
34
|
wrapper.update();
|
|
35
35
|
|
|
36
|
-
items = wrapper.find('
|
|
37
|
-
list = wrapper.find('
|
|
36
|
+
items = wrapper.find('[role="option"]');
|
|
37
|
+
list = wrapper.find('[role="listbox"]');
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
// use to remount the AssetsList at the start of a test for a clean slate
|
|
41
40
|
const resetWrapper = () => {
|
|
42
|
-
wrapper =
|
|
41
|
+
wrapper = shallowWithIntl(
|
|
43
42
|
<AssetsList
|
|
44
43
|
{...defaultProps}
|
|
45
44
|
/>);
|
|
@@ -55,132 +54,93 @@ describe('AssetsList', () => {
|
|
|
55
54
|
});
|
|
56
55
|
|
|
57
56
|
describe('renders', () => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
it('a list header', () => {
|
|
62
|
-
expect(header).toHaveLength(1);
|
|
63
|
-
});
|
|
57
|
+
it('no list header', () => {
|
|
58
|
+
expect(wrapper.find('.list-header')).toHaveLength(0);
|
|
59
|
+
});
|
|
64
60
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
});
|
|
61
|
+
it('no date-added labels', () => {
|
|
62
|
+
expect(wrapper.find('#date-added-header')).toHaveLength(0);
|
|
63
|
+
expect(wrapper.find('[id^="asset-date-"]')).toHaveLength(0);
|
|
64
|
+
});
|
|
70
65
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
expect(dateAddedLabelText.prop('message')).toEqual(messages.assetsListDateLabel);
|
|
75
|
-
});
|
|
66
|
+
it('no ordered list markup', () => {
|
|
67
|
+
expect(wrapper.find('ol')).toHaveLength(0);
|
|
68
|
+
expect(wrapper.find('li')).toHaveLength(0);
|
|
76
69
|
});
|
|
77
70
|
|
|
78
|
-
describe('a
|
|
79
|
-
it('
|
|
71
|
+
describe('a grid with', () => {
|
|
72
|
+
it('one listbox', () => {
|
|
80
73
|
expect(list).toHaveLength(1);
|
|
81
74
|
});
|
|
82
75
|
|
|
83
|
-
it('correct number of
|
|
84
|
-
expect(items).toHaveLength(defaultProps.
|
|
76
|
+
it('correct number of options', () => {
|
|
77
|
+
expect(items).toHaveLength(defaultProps.assetsList.length);
|
|
85
78
|
});
|
|
86
79
|
|
|
87
80
|
items.forEach((item, index) => {
|
|
88
|
-
|
|
89
|
-
describe('a correct thumbnail element with', () => {
|
|
90
|
-
const thumbnailElement = item.find('span').first();
|
|
91
|
-
const thumbnailElementContainer = thumbnailElement.find('div');
|
|
92
|
-
|
|
93
|
-
it('a thumbnail element', () => {
|
|
94
|
-
expect(thumbnailElement).toHaveLength(1);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('an aria-hidden attribute', () => {
|
|
98
|
-
expect(thumbnailElement.prop('aria-hidden')).toEqual(true);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('a thumbnail element', () => {
|
|
102
|
-
expect(thumbnailElement).toHaveLength(1);
|
|
103
|
-
});
|
|
81
|
+
const asset = defaultProps.assetsList[index];
|
|
104
82
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
const thumbnail = defaultProps.assetsList[index].thumbnail;
|
|
114
|
-
|
|
115
|
-
if (thumbnail) {
|
|
116
|
-
describe('an img element with', () => {
|
|
117
|
-
const imagePreviewElement = thumbnailElementContainer.find('img');
|
|
118
|
-
|
|
119
|
-
it('an img element', () => {
|
|
120
|
-
expect(imagePreviewElement).toHaveLength(1);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('an assets-list-image-preview-image className', () => {
|
|
124
|
-
expect(imagePreviewElement.prop('className').includes('assets-list-image-preview-image')).toEqual(true);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it('an empty alt', () => {
|
|
128
|
-
expect(imagePreviewElement.prop('alt')).toEqual('');
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it('correct src when courseDetails.base_url is defined', () => {
|
|
132
|
-
expect(imagePreviewElement.prop('src')).toEqual(`${defaultProps.courseDetails.base_url}${thumbnail}`);
|
|
133
|
-
});
|
|
83
|
+
describe(`an option for ${asset.display_name} with`, () => {
|
|
84
|
+
it('a file type badge', () => {
|
|
85
|
+
const badge = item.find('.file-type-badge');
|
|
86
|
+
expect(badge).toHaveLength(1);
|
|
87
|
+
expect(badge.text()).toEqual(asset.display_name.split('.').pop());
|
|
88
|
+
});
|
|
134
89
|
|
|
135
|
-
|
|
136
|
-
|
|
90
|
+
if (asset.thumbnail) {
|
|
91
|
+
describe('a thumbnail with', () => {
|
|
92
|
+
const imagePreviewElement = item.find('img.asset-thumbnail');
|
|
137
93
|
|
|
138
|
-
|
|
94
|
+
it('an img element', () => {
|
|
95
|
+
expect(imagePreviewElement).toHaveLength(1);
|
|
96
|
+
});
|
|
139
97
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
98
|
+
it('an empty alt', () => {
|
|
99
|
+
expect(imagePreviewElement.prop('alt')).toEqual('');
|
|
100
|
+
});
|
|
143
101
|
|
|
144
|
-
|
|
145
|
-
|
|
102
|
+
it('uses lazy loading', () => {
|
|
103
|
+
expect(imagePreviewElement.prop('loading')).toEqual('lazy');
|
|
146
104
|
});
|
|
147
|
-
} else {
|
|
148
|
-
describe('a noImagePreview element with', () => {
|
|
149
|
-
const noImagePreviewElement = thumbnailElementContainer.find('[data-identifier="asset-image-thumbnail"]');
|
|
150
105
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
106
|
+
it('correct src when courseDetails.base_url is defined', () => {
|
|
107
|
+
expect(imagePreviewElement.prop('src')).toEqual(`${defaultProps.courseDetails.base_url}${asset.thumbnail}`);
|
|
108
|
+
});
|
|
154
109
|
|
|
155
|
-
|
|
156
|
-
|
|
110
|
+
it('correct src when courseDetails.base_url is not defined', () => {
|
|
111
|
+
wrapper.setProps({
|
|
112
|
+
courseDetails: {
|
|
113
|
+
...defaultProps.courseDetails,
|
|
114
|
+
base_url: '',
|
|
115
|
+
},
|
|
157
116
|
});
|
|
117
|
+
updateConstants();
|
|
158
118
|
|
|
159
|
-
|
|
160
|
-
const noImagePreviewElementText = thumbnailElementContainer.find(WrappedMessage);
|
|
161
|
-
expect(noImagePreviewElementText.prop('message')).toEqual(messages.assetsListNoPreview);
|
|
162
|
-
});
|
|
119
|
+
expect(items.at(index).find('img.asset-thumbnail').prop('src')).toEqual(asset.thumbnail);
|
|
163
120
|
});
|
|
164
|
-
}
|
|
165
|
-
}
|
|
121
|
+
});
|
|
122
|
+
} else {
|
|
123
|
+
it('an icon when there is no thumbnail', () => {
|
|
124
|
+
expect(item.find('img.asset-thumbnail')).toHaveLength(0);
|
|
125
|
+
expect(item.find('.asset-icon i.far.fa-image')).toHaveLength(1);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
166
128
|
|
|
167
|
-
it('a display name
|
|
168
|
-
const displayNameElement = item.find(
|
|
129
|
+
it('a display name', () => {
|
|
130
|
+
const displayNameElement = item.find('.asset-name');
|
|
169
131
|
expect(displayNameElement).toHaveLength(1);
|
|
170
|
-
expect(displayNameElement.text()).toEqual(
|
|
132
|
+
expect(displayNameElement.text()).toEqual(asset.display_name);
|
|
171
133
|
});
|
|
172
134
|
|
|
173
|
-
it('
|
|
174
|
-
|
|
175
|
-
expect(dateAddedElement).toHaveLength(1);
|
|
176
|
-
expect(dateAddedElement.text()).toEqual(defaultProps.assetsList[index].date_added);
|
|
135
|
+
it('no date added element', () => {
|
|
136
|
+
expect(item.text()).not.toEqual(expect.stringContaining(asset.date_added));
|
|
177
137
|
});
|
|
178
138
|
});
|
|
179
139
|
});
|
|
180
140
|
});
|
|
181
141
|
});
|
|
182
142
|
|
|
183
|
-
describe('
|
|
143
|
+
describe('selection state', () => {
|
|
184
144
|
it('this.state.selectedAssetIndex is -1 by default', () => {
|
|
185
145
|
expect(wrapper.state('selectedAssetIndex')).toEqual(-1);
|
|
186
146
|
});
|
|
@@ -202,10 +162,10 @@ describe('AssetsList', () => {
|
|
|
202
162
|
expect(wrapper.state('selectedAssetIndex')).toEqual(-1);
|
|
203
163
|
});
|
|
204
164
|
|
|
205
|
-
it('this.state.selectedAssetIndex is reset to
|
|
165
|
+
it('this.state.selectedAssetIndex is reset to original index on pageChange to selectedAssetPage', () => {
|
|
206
166
|
const assetIndex = 1;
|
|
207
167
|
|
|
208
|
-
items.at(assetIndex)
|
|
168
|
+
mouseDown(items.at(assetIndex));
|
|
209
169
|
|
|
210
170
|
wrapper.setProps({
|
|
211
171
|
selectedAsset: defaultProps.assetsList[assetIndex],
|
|
@@ -231,7 +191,6 @@ describe('AssetsList', () => {
|
|
|
231
191
|
|
|
232
192
|
wrapper.setProps({
|
|
233
193
|
paginationMetadata: newPaginationData,
|
|
234
|
-
|
|
235
194
|
});
|
|
236
195
|
|
|
237
196
|
expect(wrapper.state('selectedAssetIndex')).toEqual(assetIndex);
|
|
@@ -258,17 +217,31 @@ describe('AssetsList', () => {
|
|
|
258
217
|
it('this.state.selectedAssetIndex is set by clicking on a listbox option', () => {
|
|
259
218
|
const assetIndex = 1;
|
|
260
219
|
|
|
261
|
-
items.at(assetIndex)
|
|
220
|
+
mouseDown(items.at(assetIndex));
|
|
262
221
|
|
|
263
222
|
expect(wrapper.state('selectedAssetIndex')).toEqual(assetIndex);
|
|
264
223
|
});
|
|
265
224
|
|
|
266
225
|
it('this.state.selectedAssetPage is set by clicking on a listbox option', () => {
|
|
267
|
-
items.at(1)
|
|
226
|
+
mouseDown(items.at(1));
|
|
268
227
|
|
|
269
228
|
expect(wrapper.state('selectedAssetPage')).toEqual(0);
|
|
270
229
|
});
|
|
271
230
|
|
|
231
|
+
it('scrolls the selected option into view', () => {
|
|
232
|
+
const scrollIntoView = jest.fn();
|
|
233
|
+
wrapper.instance().listRef = {
|
|
234
|
+
querySelector: () => ({ scrollIntoView }),
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
wrapper.setState({
|
|
238
|
+
selectedAssetIndex: 2,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
expect(scrollIntoView).toHaveBeenCalledTimes(1);
|
|
242
|
+
expect(scrollIntoView).toHaveBeenCalledWith({ block: 'nearest', inline: 'nearest' });
|
|
243
|
+
});
|
|
244
|
+
|
|
272
245
|
it('onAssetClick calls selectAsset prop', () => {
|
|
273
246
|
const assetIndex = 1;
|
|
274
247
|
|
|
@@ -276,7 +249,7 @@ describe('AssetsList', () => {
|
|
|
276
249
|
selectAsset: selectAssetSpy,
|
|
277
250
|
});
|
|
278
251
|
|
|
279
|
-
items.at(assetIndex)
|
|
252
|
+
mouseDown(items.at(assetIndex));
|
|
280
253
|
|
|
281
254
|
expect(selectAssetSpy).toHaveBeenCalledTimes(1);
|
|
282
255
|
expect(selectAssetSpy).toHaveBeenCalledWith(defaultProps.assetsList[assetIndex]);
|
|
@@ -286,8 +259,8 @@ describe('AssetsList', () => {
|
|
|
286
259
|
});
|
|
287
260
|
|
|
288
261
|
describe('List Box', () => {
|
|
289
|
-
it('has
|
|
290
|
-
expect(list.prop('className').includes('
|
|
262
|
+
it('has assets-grid className', () => {
|
|
263
|
+
expect(list.prop('className').includes('assets-grid')).toEqual(true);
|
|
291
264
|
});
|
|
292
265
|
|
|
293
266
|
it('has listbox role', () => {
|
|
@@ -368,31 +341,31 @@ describe('AssetsList', () => {
|
|
|
368
341
|
});
|
|
369
342
|
|
|
370
343
|
describe('has a key handler', () => {
|
|
371
|
-
const lastSelectableIndex = defaultProps.
|
|
344
|
+
const lastSelectableIndex = defaultProps.assetsList.length - 1;
|
|
372
345
|
|
|
373
|
-
describe('arrow
|
|
374
|
-
it('arrow
|
|
346
|
+
describe('arrow right', () => {
|
|
347
|
+
it('arrow right increments this.state.selectedAssetIndex if last asset is not selected', () => {
|
|
375
348
|
expect(wrapper.state('selectedAssetIndex')).toEqual(-1);
|
|
376
349
|
|
|
377
|
-
list
|
|
350
|
+
keyDown(list, 'ArrowRight');
|
|
378
351
|
|
|
379
352
|
expect(wrapper.state('selectedAssetIndex')).toEqual(0);
|
|
380
353
|
});
|
|
381
354
|
|
|
382
|
-
it('arrow
|
|
355
|
+
it('arrow right sets this.state.selectedAssetPage if last asset is not selected', () => {
|
|
383
356
|
expect(wrapper.state('selectedAssetPage')).toEqual(-1);
|
|
384
357
|
|
|
385
|
-
list
|
|
358
|
+
keyDown(list, 'ArrowRight');
|
|
386
359
|
|
|
387
360
|
expect(wrapper.state('selectedAssetPage')).toEqual(0);
|
|
388
361
|
});
|
|
389
362
|
|
|
390
|
-
it('arrow
|
|
363
|
+
it('arrow right calls selectAsset prop if last asset is not selected', () => {
|
|
391
364
|
wrapper.setProps({
|
|
392
365
|
selectAsset: selectAssetSpy,
|
|
393
366
|
});
|
|
394
367
|
|
|
395
|
-
list
|
|
368
|
+
keyDown(list, 'ArrowRight');
|
|
396
369
|
|
|
397
370
|
expect(selectAssetSpy).toHaveBeenCalledTimes(1);
|
|
398
371
|
expect(selectAssetSpy).toHaveBeenCalledWith(defaultProps.assetsList[0]);
|
|
@@ -400,27 +373,27 @@ describe('AssetsList', () => {
|
|
|
400
373
|
selectAssetSpy.mockClear();
|
|
401
374
|
});
|
|
402
375
|
|
|
403
|
-
it('arrow
|
|
376
|
+
it('arrow right does not increment this.state.selectedAssetIndex if last asset is selected', () => {
|
|
404
377
|
wrapper.setState({
|
|
405
378
|
selectedAssetIndex: lastSelectableIndex,
|
|
406
379
|
});
|
|
407
380
|
|
|
408
|
-
list
|
|
381
|
+
keyDown(list, 'ArrowRight');
|
|
409
382
|
|
|
410
383
|
expect(wrapper.state('selectedAssetIndex')).toEqual(lastSelectableIndex);
|
|
411
384
|
});
|
|
412
385
|
|
|
413
|
-
it('arrow
|
|
386
|
+
it('arrow right does not change this.state.selectedAssetPage if last asset is selected', () => {
|
|
414
387
|
wrapper.setState({
|
|
415
388
|
selectedAssetIndex: lastSelectableIndex,
|
|
416
389
|
});
|
|
417
390
|
|
|
418
|
-
list
|
|
391
|
+
keyDown(list, 'ArrowRight');
|
|
419
392
|
|
|
420
393
|
expect(wrapper.state('selectedAssetPage')).toEqual(-1);
|
|
421
394
|
});
|
|
422
395
|
|
|
423
|
-
it('arrow
|
|
396
|
+
it('arrow right does not call selectAsset prop if last asset is selected', () => {
|
|
424
397
|
wrapper.setProps({
|
|
425
398
|
selectAsset: selectAssetSpy,
|
|
426
399
|
});
|
|
@@ -429,7 +402,7 @@ describe('AssetsList', () => {
|
|
|
429
402
|
selectedAssetIndex: lastSelectableIndex,
|
|
430
403
|
});
|
|
431
404
|
|
|
432
|
-
list
|
|
405
|
+
keyDown(list, 'ArrowRight');
|
|
433
406
|
|
|
434
407
|
expect(selectAssetSpy).toHaveBeenCalledTimes(0);
|
|
435
408
|
|
|
@@ -437,28 +410,28 @@ describe('AssetsList', () => {
|
|
|
437
410
|
});
|
|
438
411
|
});
|
|
439
412
|
|
|
440
|
-
describe('arrow
|
|
413
|
+
describe('arrow left', () => {
|
|
441
414
|
it('decrements this.state.selectedAssetIndex if first asset is not selected', () => {
|
|
442
415
|
wrapper.setState({
|
|
443
416
|
selectedAssetIndex: lastSelectableIndex,
|
|
444
417
|
});
|
|
445
418
|
|
|
446
|
-
list
|
|
419
|
+
keyDown(list, 'ArrowLeft');
|
|
447
420
|
|
|
448
421
|
expect(wrapper.state('selectedAssetIndex')).toEqual(lastSelectableIndex - 1);
|
|
449
422
|
});
|
|
450
423
|
|
|
451
|
-
it('arrow
|
|
424
|
+
it('arrow left sets this.state.selectedAssetPage if first asset is not selected', () => {
|
|
452
425
|
wrapper.setState({
|
|
453
426
|
selectedAssetIndex: lastSelectableIndex,
|
|
454
427
|
});
|
|
455
428
|
|
|
456
|
-
list
|
|
429
|
+
keyDown(list, 'ArrowLeft');
|
|
457
430
|
|
|
458
431
|
expect(wrapper.state('selectedAssetPage')).toEqual(0);
|
|
459
432
|
});
|
|
460
433
|
|
|
461
|
-
it('arrow
|
|
434
|
+
it('arrow left calls selectAsset prop if first asset is not selected', () => {
|
|
462
435
|
wrapper.setProps({
|
|
463
436
|
selectAsset: selectAssetSpy,
|
|
464
437
|
});
|
|
@@ -467,7 +440,7 @@ describe('AssetsList', () => {
|
|
|
467
440
|
selectedAssetIndex: lastSelectableIndex,
|
|
468
441
|
});
|
|
469
442
|
|
|
470
|
-
list
|
|
443
|
+
keyDown(list, 'ArrowLeft');
|
|
471
444
|
|
|
472
445
|
expect(selectAssetSpy).toHaveBeenCalledTimes(1);
|
|
473
446
|
expect(selectAssetSpy)
|
|
@@ -476,32 +449,36 @@ describe('AssetsList', () => {
|
|
|
476
449
|
selectAssetSpy.mockClear();
|
|
477
450
|
});
|
|
478
451
|
|
|
479
|
-
it('arrow
|
|
452
|
+
it('arrow left does not decrement this.state.selectedAssetIndex if first asset is selected', () => {
|
|
480
453
|
wrapper.setState({
|
|
481
454
|
selectedAssetIndex: 0,
|
|
482
455
|
});
|
|
483
456
|
|
|
484
|
-
list
|
|
457
|
+
keyDown(list, 'ArrowLeft');
|
|
485
458
|
|
|
486
459
|
expect(wrapper.state('selectedAssetIndex')).toEqual(0);
|
|
487
460
|
});
|
|
488
461
|
|
|
489
|
-
it('arrow
|
|
462
|
+
it('arrow left does not change this.state.selectedAssetPage if first asset is selected', () => {
|
|
490
463
|
wrapper.setState({
|
|
491
464
|
selectedAssetIndex: 0,
|
|
492
465
|
});
|
|
493
466
|
|
|
494
|
-
list
|
|
467
|
+
keyDown(list, 'ArrowLeft');
|
|
495
468
|
|
|
496
469
|
expect(wrapper.state('selectedAssetPage')).toEqual(-1);
|
|
497
470
|
});
|
|
498
471
|
|
|
499
|
-
it('arrow
|
|
472
|
+
it('arrow left does not call selectAsset prop if first asset is selected', () => {
|
|
500
473
|
wrapper.setProps({
|
|
501
474
|
selectAsset: selectAssetSpy,
|
|
502
475
|
});
|
|
503
476
|
|
|
504
|
-
|
|
477
|
+
wrapper.setState({
|
|
478
|
+
selectedAssetIndex: 0,
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
keyDown(list, 'ArrowLeft');
|
|
505
482
|
|
|
506
483
|
expect(selectAssetSpy).toHaveBeenCalledTimes(0);
|
|
507
484
|
|
|
@@ -515,8 +492,8 @@ describe('AssetsList', () => {
|
|
|
515
492
|
items.forEach((item, index) => {
|
|
516
493
|
describe(`list box option at index ${index} has correct static props`, () => {
|
|
517
494
|
it('className', () => {
|
|
518
|
-
expect(item.prop('className').includes('
|
|
519
|
-
expect(item.prop('className').includes('
|
|
495
|
+
expect(item.prop('className').includes('asset-grid-item')).toEqual(true);
|
|
496
|
+
expect(item.prop('className').includes('selected')).toEqual(false);
|
|
520
497
|
});
|
|
521
498
|
|
|
522
499
|
it('id', () => {
|
|
@@ -531,13 +508,17 @@ describe('AssetsList', () => {
|
|
|
531
508
|
expect(item.prop('tabIndex')).toEqual('-1');
|
|
532
509
|
});
|
|
533
510
|
|
|
534
|
-
it('aria-
|
|
535
|
-
expect(item.prop('aria-
|
|
511
|
+
it('aria-label', () => {
|
|
512
|
+
expect(item.prop('aria-label')).toEqual(defaultProps.assetsList[index].display_name);
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
it('no aria-labelledby', () => {
|
|
516
|
+
expect(item.prop('aria-labelledby')).toBeUndefined();
|
|
536
517
|
});
|
|
537
518
|
});
|
|
538
519
|
});
|
|
539
520
|
|
|
540
|
-
it('has
|
|
521
|
+
it('has selected className when selected', () => {
|
|
541
522
|
const selectedAssetIndex = 2;
|
|
542
523
|
const selectedAsset = defaultProps.assetsList[selectedAssetIndex];
|
|
543
524
|
|
|
@@ -547,7 +528,7 @@ describe('AssetsList', () => {
|
|
|
547
528
|
|
|
548
529
|
updateConstants();
|
|
549
530
|
|
|
550
|
-
expect(items.at(selectedAssetIndex).prop('className').includes('
|
|
531
|
+
expect(items.at(selectedAssetIndex).prop('className').includes('selected')).toEqual(true);
|
|
551
532
|
});
|
|
552
533
|
|
|
553
534
|
it('has aria-selected attribute when selected', () => {
|
|
@@ -564,4 +545,3 @@ describe('AssetsList', () => {
|
|
|
564
545
|
});
|
|
565
546
|
});
|
|
566
547
|
});
|
|
567
|
-
|
|
@@ -2,8 +2,6 @@ import classNames from 'classnames';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
|
|
5
|
-
import WrappedMessage from '../../utils/i18n/formattedMessageWrapper';
|
|
6
|
-
import messages from './displayMessages';
|
|
7
5
|
import styles from './AssetsList.scss';
|
|
8
6
|
|
|
9
7
|
const initialState = {
|
|
@@ -51,6 +49,12 @@ export default class AssetsList extends React.Component {
|
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
|
|
52
|
+
componentDidUpdate(prevProps, prevState) {
|
|
53
|
+
if (prevState.selectedAssetIndex !== this.state.selectedAssetIndex) {
|
|
54
|
+
this.scrollSelectedOptionIntoView();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
54
58
|
onAssetClick = (asset, index) => {
|
|
55
59
|
this.setState({
|
|
56
60
|
selectedAssetIndex: index,
|
|
@@ -118,6 +122,7 @@ export default class AssetsList extends React.Component {
|
|
|
118
122
|
className={styles['asset-thumbnail']}
|
|
119
123
|
src={previewSrc}
|
|
120
124
|
alt=""
|
|
125
|
+
loading="lazy"
|
|
121
126
|
/>
|
|
122
127
|
) : (
|
|
123
128
|
<div className={styles['asset-icon']}>
|
|
@@ -142,6 +147,18 @@ export default class AssetsList extends React.Component {
|
|
|
142
147
|
getSelectedAssetIndex = (assetsList, selectedAsset) => (assetsList.findIndex(
|
|
143
148
|
asset => asset.id === selectedAsset.id));
|
|
144
149
|
|
|
150
|
+
scrollSelectedOptionIntoView = () => {
|
|
151
|
+
if (!this.listRef || this.state.selectedAssetIndex < 0) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const option = this.listRef.querySelector(`#asset-list-option-${this.state.selectedAssetIndex}`);
|
|
156
|
+
|
|
157
|
+
if (option && typeof option.scrollIntoView === 'function') {
|
|
158
|
+
option.scrollIntoView({ block: 'nearest', inline: 'nearest' });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
145
162
|
handleKeyDown = (e) => {
|
|
146
163
|
switch (e.key) {
|
|
147
164
|
case 'ArrowRight': {
|
|
@@ -184,6 +201,7 @@ export default class AssetsList extends React.Component {
|
|
|
184
201
|
className={styles['assets-grid']}
|
|
185
202
|
onFocus={this.onListBoxFocus}
|
|
186
203
|
onKeyDown={this.handleKeyDown}
|
|
204
|
+
ref={(node) => { this.listRef = node; }}
|
|
187
205
|
role="listbox"
|
|
188
206
|
tabIndex="0"
|
|
189
207
|
>
|