ReactDOM.render -> React.createRoot().render (#4338)
- await for promise that is resolved in ref attribute of root.render() as an alternative for removed callback from ReactDOM.render - await-ing for promise every time when ref needs to be used after render (e.g. tag selector container), otherwise ref will be undefined - additional window.sizeToContent calls to properly size dialogs with react-rendered content (e.g. create parent), otherwise the window can cut off some of the content.
This commit is contained in:
parent
4e0c89b352
commit
af4bbd2c4d
16 changed files with 125 additions and 107 deletions
|
@ -39,11 +39,9 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
Zotero.debug("Initializing React CollectionTree");
|
Zotero.debug("Initializing React CollectionTree");
|
||||||
var ref;
|
var ref;
|
||||||
opts.domEl = domEl;
|
opts.domEl = domEl;
|
||||||
let elem = (
|
await new Promise(resolve => {
|
||||||
<CollectionTree ref={c => ref = c } {...opts} />
|
ReactDOM.createRoot(domEl).render(<CollectionTree ref={(c) => { ref = c; resolve()} } {...opts } />)
|
||||||
);
|
});
|
||||||
await new Promise(resolve => ReactDOM.render(elem, domEl, resolve));
|
|
||||||
|
|
||||||
Zotero.debug('React CollectionTree initialized');
|
Zotero.debug('React CollectionTree initialized');
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ function AnnotationBox({ data }) {
|
||||||
Zotero.AnnotationBox = memo(AnnotationBox);
|
Zotero.AnnotationBox = memo(AnnotationBox);
|
||||||
|
|
||||||
Zotero.AnnotationBox.render = (domEl, props) => {
|
Zotero.AnnotationBox.render = (domEl, props) => {
|
||||||
ReactDOM.render(<AnnotationBox { ...props } />, domEl);
|
ReactDOM.createRoot(domEl).render(<AnnotationBox { ...props } />);
|
||||||
};
|
};
|
||||||
|
|
||||||
Zotero.AnnotationBox.destroy = (domEl) => {
|
Zotero.AnnotationBox.destroy = (domEl) => {
|
||||||
|
|
|
@ -25,12 +25,17 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { memo } from 'react';
|
import React, { memo, useEffect } from 'react';
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
|
||||||
function CreateParent({ loading, item, toggleAccept }) {
|
function CreateParent({ loading, item, toggleAccept }) {
|
||||||
|
// With React 18, this is required for the window's dialog to be properly sized
|
||||||
|
useEffect(() => {
|
||||||
|
window.sizeToContent();
|
||||||
|
}, []);
|
||||||
|
|
||||||
// When the input has/does not have characters toggle the accept button on the dialog
|
// When the input has/does not have characters toggle the accept button on the dialog
|
||||||
const handleInput = (e) => {
|
const handleInput = (e) => {
|
||||||
if (e.target.value.trim() !== '') {
|
if (e.target.value.trim() !== '') {
|
||||||
|
@ -81,5 +86,5 @@ Zotero.CreateParent.destroy = (domEl) => {
|
||||||
|
|
||||||
|
|
||||||
Zotero.CreateParent.render = (domEl, props) => {
|
Zotero.CreateParent.render = (domEl, props) => {
|
||||||
ReactDOM.render(<CreateParent { ...props } />, domEl);
|
ReactDOM.createRoot(domEl).render(<CreateParent { ...props } />);
|
||||||
};
|
};
|
||||||
|
|
|
@ -109,6 +109,7 @@ const TabBar = forwardRef(function (props, ref) {
|
||||||
updateOverflowing();
|
updateOverflowing();
|
||||||
}, 300, { leading: false });
|
}, 300, { leading: false });
|
||||||
window.addEventListener('resize', handleResize);
|
window.addEventListener('resize', handleResize);
|
||||||
|
props.onLoad();
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('resize', handleResize);
|
window.removeEventListener('resize', handleResize);
|
||||||
};
|
};
|
||||||
|
|
|
@ -857,13 +857,14 @@ Zotero.TagSelector = class TagSelectorContainer extends React.PureComponent {
|
||||||
return this.state.showAutomatic;
|
return this.state.showAutomatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
static init(domEl, opts) {
|
static async init(domEl, opts) {
|
||||||
var ref;
|
var ref;
|
||||||
let elem = (
|
await new Promise((resolve) => {
|
||||||
<TagSelectorContainer ref={c => ref = c } {...opts} />
|
ReactDOM.createRoot(domEl).render(<TagSelectorContainer ref={(c) => {
|
||||||
);
|
ref = c;
|
||||||
ReactDOM.render(elem, domEl);
|
resolve();
|
||||||
ref.domEl = domEl;
|
} } {...opts} />);
|
||||||
|
});
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,9 +169,8 @@ const Zotero_Import_Wizard = { // eslint-disable-line no-unused-vars
|
||||||
|
|
||||||
if (this.folder && !showReportErrorButton) {
|
if (this.folder && !showReportErrorButton) {
|
||||||
doneQueueContainer.style.display = 'flex';
|
doneQueueContainer.style.display = 'flex';
|
||||||
ReactDOM.render(
|
ReactDOM.createRoot(doneQueue).render(
|
||||||
<ProgressQueueTable progressQueue={ Zotero.ProgressQueues.get('recognize') } />,
|
<ProgressQueueTable progressQueue={ Zotero.ProgressQueues.get('recognize') } />
|
||||||
doneQueue
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -381,9 +380,8 @@ const Zotero_Import_Wizard = { // eslint-disable-line no-unused-vars
|
||||||
const progressQueue = document.getElementById('progress-queue');
|
const progressQueue = document.getElementById('progress-queue');
|
||||||
if (this.folder) {
|
if (this.folder) {
|
||||||
progressQueueContainer.style.display = 'flex';
|
progressQueueContainer.style.display = 'flex';
|
||||||
ReactDOM.render(
|
ReactDOM.createRoot(progressQueue).render(
|
||||||
<ProgressQueueTable progressQueue={Zotero.ProgressQueues.get('recognize')} />,
|
<ProgressQueueTable progressQueue={Zotero.ProgressQueues.get('recognize')} />
|
||||||
progressQueue
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -50,10 +50,12 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
Zotero.debug(`Initializing React ItemTree ${opts.id}`);
|
Zotero.debug(`Initializing React ItemTree ${opts.id}`);
|
||||||
var ref;
|
var ref;
|
||||||
opts.domEl = domEl;
|
opts.domEl = domEl;
|
||||||
let elem = (
|
await new Promise((resolve) => {
|
||||||
<ItemTree ref={c => ref = c } {...opts} />
|
ReactDOM.createRoot(domEl).render(<ItemTree ref={(c) => {
|
||||||
);
|
ref = c;
|
||||||
await new Promise(resolve => ReactDOM.render(elem, domEl, resolve));
|
resolve();
|
||||||
|
} } {...opts} />);
|
||||||
|
});
|
||||||
|
|
||||||
Zotero.debug(`React ItemTree ${opts.id} initialized`);
|
Zotero.debug(`React ItemTree ${opts.id} initialized`);
|
||||||
return ref;
|
return ref;
|
||||||
|
|
|
@ -39,23 +39,27 @@ const columns = [
|
||||||
function init() {
|
function init() {
|
||||||
engines = Zotero.LocateManager.getEngines();
|
engines = Zotero.LocateManager.getEngines();
|
||||||
const domEl = document.querySelector('#locateManager-tree');
|
const domEl = document.querySelector('#locateManager-tree');
|
||||||
let elem = (
|
return new Promise((resolve) => {
|
||||||
<VirtualizedTable
|
ReactDOM.createRoot(domEl).render(
|
||||||
getRowCount={() => engines.length}
|
<VirtualizedTable
|
||||||
id="locateManager-table"
|
getRowCount={() => engines.length}
|
||||||
ref={ref => tree = ref}
|
id="locateManager-table"
|
||||||
renderItem={VirtualizedTable.makeRowRenderer(getRowData)}
|
ref={(ref) => {
|
||||||
showHeader={true}
|
tree = ref;
|
||||||
multiSelect={true}
|
resolve();
|
||||||
columns={columns}
|
}}
|
||||||
onColumnSort={null}
|
renderItem={VirtualizedTable.makeRowRenderer(getRowData)}
|
||||||
disableFontSizeScaling={true}
|
showHeader={true}
|
||||||
getRowString={index => getRowData(index).name}
|
multiSelect={true}
|
||||||
onSelectionChange={handleSelectionChange}
|
columns={columns}
|
||||||
onActivate={handleActivate}
|
onColumnSort={null}
|
||||||
/>
|
disableFontSizeScaling={true}
|
||||||
);
|
getRowString={index => getRowData(index).name}
|
||||||
return new Promise(resolve => ReactDOM.render(elem, domEl, resolve));
|
onSelectionChange={handleSelectionChange}
|
||||||
|
onActivate={handleActivate}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRowData(index) {
|
function getRowData(index) {
|
||||||
|
|
|
@ -104,25 +104,28 @@ Zotero_Preferences.Cite = {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let elem = (
|
|
||||||
<VirtualizedTable
|
|
||||||
getRowCount={() => this.styles.length}
|
|
||||||
id="styleManager-table"
|
|
||||||
ref={ref => this._tree = ref}
|
|
||||||
renderItem={makeRowRenderer(index => this.styles[index])}
|
|
||||||
showHeader={true}
|
|
||||||
multiSelect={true}
|
|
||||||
columns={columns}
|
|
||||||
staticColumns={true}
|
|
||||||
disableFontSizeScaling={true}
|
|
||||||
onSelectionChange={selection => document.getElementById('styleManager-delete').disabled = !selection.count}
|
|
||||||
onKeyDown={handleKeyDown}
|
|
||||||
getRowString={index => this.styles[index].title}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
let styleManager = document.getElementById("styleManager");
|
await new Promise((resolve) => {
|
||||||
await new Promise(resolve => ReactDOM.render(elem, styleManager, resolve));
|
ReactDOM.createRoot(document.getElementById("styleManager")).render(
|
||||||
|
<VirtualizedTable
|
||||||
|
getRowCount={() => this.styles.length}
|
||||||
|
id="styleManager-table"
|
||||||
|
ref={(ref) => {
|
||||||
|
this._tree = ref;
|
||||||
|
resolve();
|
||||||
|
}}
|
||||||
|
renderItem={makeRowRenderer(index => this.styles[index])}
|
||||||
|
showHeader={true}
|
||||||
|
multiSelect={true}
|
||||||
|
columns={columns}
|
||||||
|
staticColumns={true}
|
||||||
|
disableFontSizeScaling={true}
|
||||||
|
onSelectionChange={selection => document.getElementById('styleManager-delete').disabled = !selection.count}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
|
getRowString={index => this.styles[index].title}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// Fix style manager showing partially blank until scrolled
|
// Fix style manager showing partially blank until scrolled
|
||||||
setTimeout(() => this._tree.invalidate());
|
setTimeout(() => this._tree.invalidate());
|
||||||
|
|
|
@ -485,23 +485,27 @@ Zotero_Preferences.Export = {
|
||||||
this.updateQuickCopySiteButtons();
|
this.updateQuickCopySiteButtons();
|
||||||
};
|
};
|
||||||
|
|
||||||
let elem = (
|
await new Promise((resolve) => {
|
||||||
<VirtualizedTable
|
ReactDOM.createRoot(document.getElementById("quickCopy-siteSettings")).render(
|
||||||
getRowCount={() => this._rows.length}
|
<VirtualizedTable
|
||||||
id="quickCopy-siteSettings-table"
|
getRowCount={() => this._rows.length}
|
||||||
ref={ref => this._tree = ref}
|
id="quickCopy-siteSettings-table"
|
||||||
renderItem={makeRowRenderer(index => this._rows[index])}
|
ref={(ref) => {
|
||||||
showHeader={true}
|
this._tree = ref;
|
||||||
columns={columns}
|
resolve();
|
||||||
staticColumns={true}
|
}}
|
||||||
disableFontSizeScaling={true}
|
renderItem={makeRowRenderer(index => this._rows[index])}
|
||||||
onSelectionChange={handleSelectionChange}
|
showHeader={true}
|
||||||
onKeyDown={handleKeyDown}
|
columns={columns}
|
||||||
getRowString={index => this._rows[index].domain}
|
staticColumns={true}
|
||||||
onActivate={(event, indices) => Zotero_Preferences.Export.showQuickCopySiteEditor(true)}
|
disableFontSizeScaling={true}
|
||||||
/>
|
onSelectionChange={handleSelectionChange}
|
||||||
);
|
onKeyDown={handleKeyDown}
|
||||||
await new Promise(resolve => ReactDOM.render(elem, document.getElementById("quickCopy-siteSettings"), resolve));
|
getRowString={index => this._rows[index].domain}
|
||||||
|
onActivate={(event, indices) => Zotero_Preferences.Export.showQuickCopySiteEditor(true)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this._tree.invalidate();
|
this._tree.invalidate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,22 +315,25 @@ Zotero_Preferences.Sync = {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let elem = (
|
await new Promise((resolve) => {
|
||||||
<VirtualizedTable
|
ReactDOM.createRoot(document.getElementById("libraries-to-sync-tree")).render(
|
||||||
getRowCount={() => this._rows.length}
|
<VirtualizedTable
|
||||||
id="librariesToSync-table"
|
getRowCount={() => this._rows.length}
|
||||||
ref={ref => this._tree = ref}
|
id="librariesToSync-table"
|
||||||
renderItem={renderItem}
|
ref={(ref) => {
|
||||||
showHeader={true}
|
this._tree = ref;
|
||||||
columns={columns}
|
resolve();
|
||||||
staticColumns={true}
|
}}
|
||||||
getRowString={index => this._rows[index].name}
|
renderItem={renderItem}
|
||||||
disableFontSizeScaling={true}
|
showHeader={true}
|
||||||
onKeyDown={handleKeyDown}
|
columns={columns}
|
||||||
/>
|
staticColumns={true}
|
||||||
);
|
getRowString={index => this._rows[index].name}
|
||||||
|
disableFontSizeScaling={true}
|
||||||
ReactDOM.render(elem, document.getElementById("libraries-to-sync-tree"));
|
onKeyDown={handleKeyDown}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
var addRow = function (libraryName, id, checked=false, editable=true) {
|
var addRow = function (libraryName, id, checked=false, editable=true) {
|
||||||
this._rows.push({
|
this._rows.push({
|
||||||
|
|
|
@ -37,13 +37,11 @@ function _init() {
|
||||||
|
|
||||||
const domEl = document.querySelector('#tree');
|
const domEl = document.querySelector('#tree');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.createRoot(domEl).render(
|
||||||
<ProgressQueueTable
|
<ProgressQueueTable
|
||||||
onActivate={ _handleActivate }
|
onActivate={ _handleActivate }
|
||||||
progressQueue={ _progressQueue }
|
progressQueue={ _progressQueue }
|
||||||
/>,
|
/>);
|
||||||
domEl
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -145,7 +145,7 @@ const Zotero_RTFScan = { // eslint-disable-line no-unused-vars, camelcase
|
||||||
.getElementById('choose-output-file')
|
.getElementById('choose-output-file')
|
||||||
.addEventListener('click', this.onChooseOutputFile.bind(this));
|
.addEventListener('click', this.onChooseOutputFile.bind(this));
|
||||||
|
|
||||||
ReactDOM.render((
|
ReactDOM.createRoot(document.getElementById('tree')).render((
|
||||||
<VirtualizedTable
|
<VirtualizedTable
|
||||||
getRowCount={() => this.rows.length}
|
getRowCount={() => this.rows.length}
|
||||||
id="rtfScan-table"
|
id="rtfScan-table"
|
||||||
|
@ -156,7 +156,7 @@ const Zotero_RTFScan = { // eslint-disable-line no-unused-vars, camelcase
|
||||||
containerWidth={document.getElementById('tree').clientWidth}
|
containerWidth={document.getElementById('tree').clientWidth}
|
||||||
disableFontSizeScaling={true}
|
disableFontSizeScaling={true}
|
||||||
/>
|
/>
|
||||||
), document.getElementById('tree'));
|
));
|
||||||
|
|
||||||
const lastInputFile = Zotero.Prefs.get("rtfScan.lastInputFile");
|
const lastInputFile = Zotero.Prefs.get("rtfScan.lastInputFile");
|
||||||
if (lastInputFile) {
|
if (lastInputFile) {
|
||||||
|
|
|
@ -165,7 +165,7 @@ var Zotero_Tabs = new function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.init = function () {
|
this.init = function () {
|
||||||
ReactDOM.render(
|
ReactDOM.createRoot(document.getElementById('tab-bar-container')).render(
|
||||||
<TabBar
|
<TabBar
|
||||||
ref={this._tabBarRef}
|
ref={this._tabBarRef}
|
||||||
onTabSelect={this.select.bind(this)}
|
onTabSelect={this.select.bind(this)}
|
||||||
|
@ -173,11 +173,8 @@ var Zotero_Tabs = new function () {
|
||||||
onTabClose={this.close.bind(this)}
|
onTabClose={this.close.bind(this)}
|
||||||
onContextMenu={this._openMenu.bind(this)}
|
onContextMenu={this._openMenu.bind(this)}
|
||||||
refocusReader={this.refocusReader.bind(this)}
|
refocusReader={this.refocusReader.bind(this)}
|
||||||
/>,
|
onLoad={this._update.bind(this)}
|
||||||
document.getElementById('tab-bar-container'),
|
/>
|
||||||
() => {
|
|
||||||
this._update();
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ const ReactDOM = require('react-dom');
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
let div = document.querySelector('div');
|
let div = document.querySelector('div');
|
||||||
ReactDOM.render(<DataGeneratorForm/>, div);
|
ReactDOM.createRoot(div).render(<DataGeneratorForm/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DataGeneratorForm extends React.Component {
|
class DataGeneratorForm extends React.Component {
|
||||||
|
@ -44,6 +44,10 @@ class DataGeneratorForm extends React.Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
window.sizeToContent();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -1688,11 +1688,11 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.initTagSelector = function () {
|
this.initTagSelector = async function () {
|
||||||
try {
|
try {
|
||||||
var container = document.getElementById('zotero-tag-selector-container');
|
var container = document.getElementById('zotero-tag-selector-container');
|
||||||
if (!container.hasAttribute('collapsed') || container.getAttribute('collapsed') == 'false') {
|
if (!container.hasAttribute('collapsed') || container.getAttribute('collapsed') == 'false') {
|
||||||
this.tagSelector = Zotero.TagSelector.init(
|
this.tagSelector = await Zotero.TagSelector.init(
|
||||||
document.getElementById('zotero-tag-selector'),
|
document.getElementById('zotero-tag-selector'),
|
||||||
{
|
{
|
||||||
container: 'zotero-tag-selector-container',
|
container: 'zotero-tag-selector-container',
|
||||||
|
|
Loading…
Add table
Reference in a new issue