Skip to content

Commit 2f7beb6

Browse files
authored
TagBox: fix async fieldTemplate rendering in React 18 (T1283948) (DevExpress#29489)
1 parent b3767ad commit 2f7beb6

File tree

4 files changed

+209
-78
lines changed

4 files changed

+209
-78
lines changed

apps/react/examples/Examples.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import ValidationExample from './validation-example';
2626
import SelectBoxTemplatesExample from './selectbox-templates-example';
2727
import SelectBoxFieldTemplateExample from './selectbox-fieldtemplate-example';
2828
import SelectBoxParallelTemplateRenderExample from './selectbox-parallel-template-render-example';
29+
import TagBoxFieldTemplateCheckBoxesExample from './tagbox-fieldtemplate-checkboxes-example';
2930

3031
const Examples = () => {
3132
return (
@@ -92,6 +93,10 @@ const Examples = () => {
9293
<SelectBoxTemplatesExample />
9394
</Example>
9495

96+
<Example title="TagBox with field template and showSelectionControls=true">
97+
<TagBoxFieldTemplateCheckBoxesExample />
98+
</Example>
99+
95100
<Example title="SelectBox example with field template (controlled mode)">
96101
<SelectBoxFieldTemplateExample />
97102
</Example>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react';
2+
import { TagBox } from 'devextreme-react/tag-box';
3+
import { TextBox } from 'devextreme-react/text-box';
4+
5+
function Field() {
6+
return (<TextBox placeholder="test" />);
7+
}
8+
9+
const items = ['Item 1', 'Item 2', 'Item 3'];
10+
11+
export default (): React.ReactElement | null => {
12+
return (
13+
<TagBox
14+
items={items}
15+
showSelectionControls={true}
16+
fieldRender={Field}
17+
/>
18+
);
19+
};

packages/devextreme/js/__internal/ui/m_tag_box.ts

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -657,10 +657,7 @@ const TagBox = (SelectBox as any).inherit({
657657
this._updateTagsContainer(this._$textEditorInputContainer);
658658
this._renderInputSize();
659659
this._renderTags()
660-
.done(() => {
661-
this._popup && this._popup.refreshPosition();
662-
d.resolve();
663-
})
660+
.done(d.resolve)
664661
.fail(d.reject);
665662

666663
return d.promise();
@@ -956,7 +953,8 @@ const TagBox = (SelectBox as any).inherit({
956953
this._selectedItems = this._getItemsFromPlain(this._valuesToUpdate);
957954

958955
if (this._selectedItems.length === this._valuesToUpdate.length) {
959-
this._renderTagsImpl(this._selectedItems);
956+
this._tagsToRender = this._selectedItems;
957+
this._renderTagsImpl();
960958
isPlainDataUsed = true;
961959
d.resolve();
962960
}
@@ -970,7 +968,8 @@ const TagBox = (SelectBox as any).inherit({
970968
return;
971969
}
972970

973-
this._renderTagsImpl(items);
971+
this._tagsToRender = items;
972+
this._renderTagsImpl();
974973
d.resolve();
975974
})
976975
.fail(d.reject);
@@ -979,12 +978,15 @@ const TagBox = (SelectBox as any).inherit({
979978
return d.promise();
980979
},
981980

982-
_renderTagsImpl(items) {
983-
this._renderTagsCore(items);
984-
this._renderEmptyState();
981+
_renderTagsImpl(): void {
982+
this._renderField();
985983

986-
if (!this._preserveFocusedTag) {
987-
this._clearTagFocus();
984+
this.option('selectedItems', this._selectedItems.slice());
985+
this._cleanTags();
986+
987+
const fieldTemplate = this._getFieldTemplate();
988+
if (!fieldTemplate) {
989+
this._renderTagsCore();
988990
}
989991
},
990992

@@ -1042,31 +1044,24 @@ const TagBox = (SelectBox as any).inherit({
10421044
},
10431045

10441046
_integrateInput() {
1045-
this._isInputReady.resolve();
10461047
this.callBase();
10471048

10481049
const tagsContainer = this.$element().find(`.${TEXTEDITOR_INPUT_CONTAINER_CLASS}`);
10491050

10501051
this._updateTagsContainer(tagsContainer);
10511052
this._renderTagRemoveAction();
1053+
this._renderTagsCore();
10521054
},
10531055

1054-
_renderTagsCore(items) {
1055-
this._isInputReady?.reject();
1056-
1057-
this._isInputReady = Deferred();
1058-
this._renderField();
1059-
1060-
this.option('selectedItems', this._selectedItems.slice());
1061-
this._cleanTags();
1056+
_renderTagsCore() {
1057+
this._renderTagsElements(this._tagsToRender);
1058+
this._renderEmptyState();
10621059

1063-
if (this._input().length > 0) {
1064-
this._isInputReady.resolve();
1060+
if (!this._preserveFocusedTag) {
1061+
this._clearTagFocus();
10651062
}
10661063

1067-
when(this._isInputReady).done(() => {
1068-
this._renderTagsElements(items);
1069-
});
1064+
this._popup?.refreshPosition();
10701065
},
10711066

10721067
_renderTagsElements(items) {
@@ -1534,6 +1529,7 @@ const TagBox = (SelectBox as any).inherit({
15341529
delete this._defaultTagTemplate;
15351530
delete this._valuesToUpdate;
15361531
delete this._tagTemplate;
1532+
delete this._tagsToRender;
15371533
},
15381534

15391535
_getSelectedItemsDifference(newItems, previousItems) {

0 commit comments

Comments
 (0)