decap-cms-widget-list 3.6.3-beta.0 → 3.6.3
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "decap-cms-widget-list",
|
|
3
3
|
"description": "Widget for editing lists in Decap CMS.",
|
|
4
|
-
"version": "3.6.3
|
|
4
|
+
"version": "3.6.3",
|
|
5
5
|
"homepage": "https://www.decapcms.org/docs/widgets/#list",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"react": "^19.1.0",
|
|
34
34
|
"react-immutable-proptypes": "^2.1.0",
|
|
35
35
|
"uuid": "^8.3.2",
|
|
36
|
-
"decap-cms-lib-widgets": "3.4.
|
|
37
|
-
"decap-cms-
|
|
38
|
-
"decap-cms-
|
|
36
|
+
"decap-cms-lib-widgets": "3.4.2",
|
|
37
|
+
"decap-cms-ui-default": "3.9.2",
|
|
38
|
+
"decap-cms-widget-object": "3.7.3"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"develop": "pnpm run build:esm --watch",
|
package/src/ListControl.js
CHANGED
|
@@ -6,6 +6,7 @@ import { css, ClassNames } from '@emotion/react';
|
|
|
6
6
|
import { List, Map, fromJS } from 'immutable';
|
|
7
7
|
import partial from 'lodash/partial';
|
|
8
8
|
import isEmpty from 'lodash/isEmpty';
|
|
9
|
+
import memoize from 'lodash/memoize';
|
|
9
10
|
import uniqueId from 'lodash/uniqueId';
|
|
10
11
|
import DecapCmsWidgetObject from 'decap-cms-widget-object';
|
|
11
12
|
import {
|
|
@@ -255,10 +256,18 @@ export default class ListControl extends Component {
|
|
|
255
256
|
|
|
256
257
|
uniqueFieldId = uniqueId(`${this.props.field.get('name')}-field-`);
|
|
257
258
|
/**
|
|
259
|
+
* Old comment:
|
|
260
|
+
*
|
|
258
261
|
* Always update so that each nested widget has the option to update. This is
|
|
259
262
|
* required because ControlHOC provides a default `shouldComponentUpdate`
|
|
260
263
|
* which only updates if the value changes, but every widget must be allowed
|
|
261
264
|
* to override this.
|
|
265
|
+
*
|
|
266
|
+
* New comment:
|
|
267
|
+
*
|
|
268
|
+
* Each Widget is wrapped with EditorControl which already tries to update every time.
|
|
269
|
+
* Is there a specific reason we need to always rerender the list?
|
|
270
|
+
* This seems overkill.
|
|
262
271
|
*/
|
|
263
272
|
shouldComponentUpdate() {
|
|
264
273
|
return true;
|
|
@@ -418,15 +427,18 @@ export default class ListControl extends Component {
|
|
|
418
427
|
*/
|
|
419
428
|
getObjectValue = idx => this.props.value.get(idx) || Map();
|
|
420
429
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
430
|
+
/**
|
|
431
|
+
* Memoized on the item's key rather than its position, so each item keeps a
|
|
432
|
+
* stable `onChangeObject` reference across renders and reorders.
|
|
433
|
+
*/
|
|
434
|
+
handleChangeFor = memoize(key => {
|
|
424
435
|
return (f, newValue, newMetadata) => {
|
|
425
436
|
const { value, metadata, onChange, field } = this.props;
|
|
426
437
|
|
|
427
438
|
// Resolve the item's position when the change fires rather than when this
|
|
428
|
-
// handler was created. If
|
|
429
|
-
//
|
|
439
|
+
// handler was created. If the item has been removed or moved in between,
|
|
440
|
+
// its old position now points at a different item, or past the end of the
|
|
441
|
+
// list.
|
|
430
442
|
const currentIndex = this.state.keys.indexOf(key);
|
|
431
443
|
|
|
432
444
|
if (currentIndex === -1) {
|
|
@@ -446,7 +458,7 @@ export default class ListControl extends Component {
|
|
|
446
458
|
};
|
|
447
459
|
onChange(value.set(currentIndex, newObjectValue), parsedMetadata);
|
|
448
460
|
};
|
|
449
|
-
}
|
|
461
|
+
});
|
|
450
462
|
|
|
451
463
|
handleRemove = (index, event) => {
|
|
452
464
|
event.preventDefault();
|
|
@@ -641,6 +653,11 @@ export default class ListControl extends Component {
|
|
|
641
653
|
}
|
|
642
654
|
}
|
|
643
655
|
|
|
656
|
+
getStableParentIds = memoize(
|
|
657
|
+
(parentIds, forID, key) => [...parentIds, forID, key],
|
|
658
|
+
(parentIds, forID, key) => JSON.stringify([...parentIds, forID, key]),
|
|
659
|
+
);
|
|
660
|
+
|
|
644
661
|
// eslint-disable-next-line react/display-name
|
|
645
662
|
renderItem = (item, index) => {
|
|
646
663
|
const {
|
|
@@ -711,7 +728,7 @@ export default class ListControl extends Component {
|
|
|
711
728
|
})}
|
|
712
729
|
value={item}
|
|
713
730
|
field={field}
|
|
714
|
-
onChangeObject={this.handleChangeFor(
|
|
731
|
+
onChangeObject={this.handleChangeFor(key)}
|
|
715
732
|
editorControl={editorControl}
|
|
716
733
|
resolveWidget={resolveWidget}
|
|
717
734
|
metadata={metadata}
|
|
@@ -725,7 +742,7 @@ export default class ListControl extends Component {
|
|
|
725
742
|
collapsed={collapsed}
|
|
726
743
|
data-testid={`object-control-${key}`}
|
|
727
744
|
hasError={hasError}
|
|
728
|
-
parentIds={
|
|
745
|
+
parentIds={this.getStableParentIds(parentIds, forID, key)}
|
|
729
746
|
/>
|
|
730
747
|
)}
|
|
731
748
|
</ClassNames>
|
|
@@ -811,7 +811,7 @@ describe('ListControl', () => {
|
|
|
811
811
|
<ListControl ref={ref => (control = ref)} {...props} field={typedField} value={value} />,
|
|
812
812
|
);
|
|
813
813
|
|
|
814
|
-
const changeThirdItem = control.handleChangeFor(2);
|
|
814
|
+
const changeThirdItem = control.handleChangeFor(control.state.keys[2]);
|
|
815
815
|
|
|
816
816
|
fireEvent.click(getAllByText('Remove')[0]);
|
|
817
817
|
const afterRemoval = props.onChange.mock.calls[0][0];
|
|
@@ -842,7 +842,7 @@ describe('ListControl', () => {
|
|
|
842
842
|
<ListControl ref={ref => (control = ref)} {...props} field={typedField} value={value} />,
|
|
843
843
|
);
|
|
844
844
|
|
|
845
|
-
const changeSecondItem = control.handleChangeFor(1);
|
|
845
|
+
const changeSecondItem = control.handleChangeFor(control.state.keys[1]);
|
|
846
846
|
|
|
847
847
|
fireEvent.click(getAllByText('Remove')[1]);
|
|
848
848
|
const afterRemoval = props.onChange.mock.calls[0][0];
|