Switching to use React.createRef
This commit is contained in:
parent
f5f30a854b
commit
f0062c94be
@ -114,8 +114,8 @@ class App extends React.PureComponent {
|
|||||||
expr
|
expr
|
||||||
}, async () => {
|
}, async () => {
|
||||||
await this.image.doReflow();
|
await this.image.doReflow();
|
||||||
this.setSvgUrl(this.image.svg);
|
this.setSvgUrl(this.image.svg.current);
|
||||||
this.setPngUrl(this.image.svg);
|
this.setPngUrl(this.image.svg.current);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,10 +12,14 @@ class Box extends React.PureComponent {
|
|||||||
radius: 3
|
radius: 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label = React.createRef()
|
||||||
|
|
||||||
|
children = [React.createRef()]
|
||||||
|
|
||||||
reflow() {
|
reflow() {
|
||||||
const { padding, useAnchors } = this.props;
|
const { padding, useAnchors } = this.props;
|
||||||
const box = this.children[0].getBBox();
|
const box = this.children[0].current.getBBox();
|
||||||
const labelBox = this.label ? this.label.getBBox() : { width: 0, height: 0};
|
const labelBox = this.label.current ? this.label.current.getBBox() : { width: 0, height: 0};
|
||||||
|
|
||||||
this.setBBox({
|
this.setBBox({
|
||||||
width: Math.max(box.width + 2 * padding, labelBox.width),
|
width: Math.max(box.width + 2 * padding, labelBox.width),
|
||||||
@ -34,10 +38,6 @@ class Box extends React.PureComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
containedRef = contained => this.children = [contained]
|
|
||||||
|
|
||||||
labelRef = label => this.label = label
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { theme, radius, label, children } = this.props;
|
const { theme, radius, label, children } = this.props;
|
||||||
const { width, height, labelTransform, rectTransform, contentTransform } = this.state || {};
|
const { width, height, labelTransform, rectTransform, contentTransform } = this.state || {};
|
||||||
@ -53,7 +53,7 @@ class Box extends React.PureComponent {
|
|||||||
const textProps = {
|
const textProps = {
|
||||||
transform: labelTransform,
|
transform: labelTransform,
|
||||||
style: style.infoText,
|
style: style.infoText,
|
||||||
ref: this.labelRef
|
ref: this.label
|
||||||
};
|
};
|
||||||
|
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
@ -61,7 +61,7 @@ class Box extends React.PureComponent {
|
|||||||
{ label && <text { ...textProps }>{ label }</text> }
|
{ label && <text { ...textProps }>{ label }</text> }
|
||||||
<g transform={ contentTransform }>
|
<g transform={ contentTransform }>
|
||||||
{ React.cloneElement(React.Children.only(children), {
|
{ React.cloneElement(React.Children.only(children), {
|
||||||
ref: this.containedRef
|
ref: this.children[0]
|
||||||
}) }
|
}) }
|
||||||
</g>
|
</g>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
|
@ -18,6 +18,8 @@ class HorizontalLayout extends React.PureComponent {
|
|||||||
childTransforms: List()
|
childTransforms: List()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
children = []
|
||||||
|
|
||||||
updateChildTransforms(childBoxes) {
|
updateChildTransforms(childBoxes) {
|
||||||
return this.state.childTransforms.withMutations(transforms => (
|
return this.state.childTransforms.withMutations(transforms => (
|
||||||
childBoxes.forEach((box, i) => (
|
childBoxes.forEach((box, i) => (
|
||||||
@ -44,7 +46,7 @@ class HorizontalLayout extends React.PureComponent {
|
|||||||
reflow() {
|
reflow() {
|
||||||
const { spacing, withConnectors } = this.props;
|
const { spacing, withConnectors } = this.props;
|
||||||
|
|
||||||
const childBoxes = this.children.map(child => child.getBBox());
|
const childBoxes = this.children.map(child => child.current.getBBox());
|
||||||
const verticalCenter = childBoxes.reduce((center, box) => Math.max(center, box.axisY), 0);
|
const verticalCenter = childBoxes.reduce((center, box) => Math.max(center, box.axisY), 0);
|
||||||
const width = childBoxes.reduce((width, box) => width + box.width, 0) + (childBoxes.length - 1) * spacing;
|
const width = childBoxes.reduce((width, box) => width + box.width, 0) + (childBoxes.length - 1) * spacing;
|
||||||
const height = childBoxes.reduce((ascHeight, box) => Math.max(ascHeight, box.axisY), 0) +
|
const height = childBoxes.reduce((ascHeight, box) => Math.max(ascHeight, box.axisY), 0) +
|
||||||
@ -64,20 +66,18 @@ class HorizontalLayout extends React.PureComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
childRef = i => child => this.children[i] = child
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { children } = this.props;
|
const { children } = this.props;
|
||||||
const { childTransforms, connectorPaths } = this.state;
|
const { childTransforms, connectorPaths } = this.state;
|
||||||
|
|
||||||
this.children = [];
|
this.makeRefCollection(this.children, React.Children.count(children));
|
||||||
|
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<path d={ connectorPaths } style={ style.connectors }></path>
|
<path d={ connectorPaths } style={ style.connectors }></path>
|
||||||
{ React.Children.map(children, (child, i) => (
|
{ React.Children.map(children, (child, i) => (
|
||||||
<g transform={ childTransforms.get(i) }>
|
<g transform={ childTransforms.get(i) }>
|
||||||
{ React.cloneElement(child, {
|
{ React.cloneElement(child, {
|
||||||
ref: this.childRef(i)
|
ref: this.children[i]
|
||||||
}) }
|
}) }
|
||||||
</g>
|
</g>
|
||||||
))}
|
))}
|
||||||
|
@ -31,9 +31,13 @@ class Image extends React.PureComponent {
|
|||||||
height: 0
|
height: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svg = React.createRef()
|
||||||
|
|
||||||
|
children = [React.createRef()]
|
||||||
|
|
||||||
reflow() {
|
reflow() {
|
||||||
const { padding } = this.props;
|
const { padding } = this.props;
|
||||||
const box = this.children[0].getBBox();
|
const box = this.children[0].current.getBBox();
|
||||||
|
|
||||||
this.setStateAsync({
|
this.setStateAsync({
|
||||||
width: Math.round(box.width + 2 * padding),
|
width: Math.round(box.width + 2 * padding),
|
||||||
@ -41,10 +45,6 @@ class Image extends React.PureComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
containedRef = contained => this.children = [contained]
|
|
||||||
|
|
||||||
svgRef = svg => this.svg = svg
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { width, height } = this.state;
|
const { width, height } = this.state;
|
||||||
const { padding, children } = this.props;
|
const { padding, children } = this.props;
|
||||||
@ -54,7 +54,7 @@ class Image extends React.PureComponent {
|
|||||||
height,
|
height,
|
||||||
viewBox: [0, 0, width, height].join(' '),
|
viewBox: [0, 0, width, height].join(' '),
|
||||||
style: style.image,
|
style: style.image,
|
||||||
ref: this.svgRef,
|
ref: this.svg,
|
||||||
...namespaceProps
|
...namespaceProps
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ class Image extends React.PureComponent {
|
|||||||
<metadata dangerouslySetInnerHTML={{ __html: metadata }}></metadata>
|
<metadata dangerouslySetInnerHTML={{ __html: metadata }}></metadata>
|
||||||
<g transform={ `translate(${ padding } ${ padding })` }>
|
<g transform={ `translate(${ padding } ${ padding })` }>
|
||||||
{ React.cloneElement(React.Children.only(children), {
|
{ React.cloneElement(React.Children.only(children), {
|
||||||
ref: this.containedRef
|
ref: this.children[0]
|
||||||
}) }
|
}) }
|
||||||
</g>
|
</g>
|
||||||
</svg>;
|
</svg>;
|
||||||
|
@ -57,6 +57,10 @@ const repeatPath = (box, greedy) => {
|
|||||||
|
|
||||||
@reflowable
|
@reflowable
|
||||||
class Loop extends React.PureComponent {
|
class Loop extends React.PureComponent {
|
||||||
|
label = React.createRef()
|
||||||
|
|
||||||
|
children = [React.createRef()]
|
||||||
|
|
||||||
get contentOffset() {
|
get contentOffset() {
|
||||||
const { skip, repeat } = this.props;
|
const { skip, repeat } = this.props;
|
||||||
|
|
||||||
@ -71,8 +75,8 @@ class Loop extends React.PureComponent {
|
|||||||
|
|
||||||
reflow() {
|
reflow() {
|
||||||
const { skip, repeat, greedy } = this.props;
|
const { skip, repeat, greedy } = this.props;
|
||||||
const box = this.children[0].getBBox();
|
const box = this.children[0].current.getBBox();
|
||||||
const labelBox = this.label ? this.label.getBBox() : { width: 0, height: 0 };
|
const labelBox = this.label.current ? this.label.current.getBBox() : { width: 0, height: 0 };
|
||||||
|
|
||||||
let height = box.height + labelBox.height;
|
let height = box.height + labelBox.height;
|
||||||
if (skip) {
|
if (skip) {
|
||||||
@ -102,10 +106,6 @@ class Loop extends React.PureComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
containedRef = contained => this.children = [contained]
|
|
||||||
|
|
||||||
labelRef = label => this.label = label
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { label, children } = this.props;
|
const { label, children } = this.props;
|
||||||
const { loopPaths, labelTransform } = this.state || {};
|
const { loopPaths, labelTransform } = this.state || {};
|
||||||
@ -113,7 +113,7 @@ class Loop extends React.PureComponent {
|
|||||||
const textProps = {
|
const textProps = {
|
||||||
transform: labelTransform,
|
transform: labelTransform,
|
||||||
style: style.infoText,
|
style: style.infoText,
|
||||||
ref: this.labelRef
|
ref: this.label
|
||||||
};
|
};
|
||||||
|
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
@ -121,7 +121,7 @@ class Loop extends React.PureComponent {
|
|||||||
{ label && <text { ...textProps }>{ label }</text> }
|
{ label && <text { ...textProps }>{ label }</text> }
|
||||||
<g transform={ `translate(${ this.contentOffset.x } ${ this.contentOffset.y })` }>
|
<g transform={ `translate(${ this.contentOffset.x } ${ this.contentOffset.y })` }>
|
||||||
{ React.cloneElement(React.Children.only(children), {
|
{ React.cloneElement(React.Children.only(children), {
|
||||||
ref: this.containedRef
|
ref: this.children[0]
|
||||||
}) }
|
}) }
|
||||||
</g>
|
</g>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
|
@ -7,8 +7,10 @@ import reflowable from './reflowable';
|
|||||||
|
|
||||||
@reflowable
|
@reflowable
|
||||||
class Text extends React.PureComponent {
|
class Text extends React.PureComponent {
|
||||||
|
text = React.createRef()
|
||||||
|
|
||||||
reflow() {
|
reflow() {
|
||||||
const box = this.text.getBBox();
|
const box = this.text.current.getBBox();
|
||||||
|
|
||||||
this.setBBox({
|
this.setBBox({
|
||||||
width: box.width,
|
width: box.width,
|
||||||
@ -20,8 +22,6 @@ class Text extends React.PureComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
textRef = text => this.text = text
|
|
||||||
|
|
||||||
renderContent() {
|
renderContent() {
|
||||||
const { children, quoted } = this.props;
|
const { children, quoted } = this.props;
|
||||||
if (!quoted) {
|
if (!quoted) {
|
||||||
@ -42,7 +42,7 @@ class Text extends React.PureComponent {
|
|||||||
const textProps = {
|
const textProps = {
|
||||||
style: { ...style.text, ...style[theme] },
|
style: { ...style.text, ...style[theme] },
|
||||||
transform,
|
transform,
|
||||||
ref: this.textRef
|
ref: this.text
|
||||||
};
|
};
|
||||||
|
|
||||||
return <text { ...textProps }>
|
return <text { ...textProps }>
|
||||||
|
@ -20,6 +20,8 @@ class VerticalLayout extends React.PureComponent {
|
|||||||
childTransforms: List()
|
childTransforms: List()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
children = []
|
||||||
|
|
||||||
updateChildTransforms(childBoxes) {
|
updateChildTransforms(childBoxes) {
|
||||||
return this.state.childTransforms.withMutations(transforms => (
|
return this.state.childTransforms.withMutations(transforms => (
|
||||||
childBoxes.forEach((box, i) => (
|
childBoxes.forEach((box, i) => (
|
||||||
@ -82,7 +84,7 @@ class VerticalLayout extends React.PureComponent {
|
|||||||
reflow() {
|
reflow() {
|
||||||
const { spacing, withConnectors } = this.props;
|
const { spacing, withConnectors } = this.props;
|
||||||
|
|
||||||
const childBoxes = this.children.map(child => child.getBBox());
|
const childBoxes = this.children.map(child => child.current.getBBox());
|
||||||
const horizontalCenter = childBoxes.reduce((center, box) => Math.max(center, box.width / 2), 0);
|
const horizontalCenter = childBoxes.reduce((center, box) => Math.max(center, box.width / 2), 0);
|
||||||
const margin = withConnectors ? connectorMargin : 0;
|
const margin = withConnectors ? connectorMargin : 0;
|
||||||
const width = childBoxes.reduce((width, box) => Math.max(width, box.width), 0) + 2 * margin;
|
const width = childBoxes.reduce((width, box) => Math.max(width, box.width), 0) + 2 * margin;
|
||||||
@ -106,20 +108,18 @@ class VerticalLayout extends React.PureComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
childRef = i => child => this.children[i] = child
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { children } = this.props;
|
const { children } = this.props;
|
||||||
const { childTransforms, connectorPaths } = this.state;
|
const { childTransforms, connectorPaths } = this.state;
|
||||||
|
|
||||||
this.children = [];
|
this.makeRefCollection(this.children, React.Children.count(children));
|
||||||
|
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<path d={ connectorPaths } style={ style.connectors }></path>
|
<path d={ connectorPaths } style={ style.connectors }></path>
|
||||||
{ React.Children.map(children, (child, i) => (
|
{ React.Children.map(children, (child, i) => (
|
||||||
<g transform={ childTransforms.get(i) }>
|
<g transform={ childTransforms.get(i) }>
|
||||||
{ React.cloneElement(child, {
|
{ React.cloneElement(child, {
|
||||||
ref: this.childRef(i)
|
ref: this.children[i]
|
||||||
}) }
|
}) }
|
||||||
</g>
|
</g>
|
||||||
)) }
|
)) }
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import React from 'react';
|
||||||
import { Map } from 'immutable';
|
import { Map } from 'immutable';
|
||||||
|
|
||||||
const reflowable = Component => {
|
const reflowable = Component => {
|
||||||
@ -46,13 +47,24 @@ const reflowable = Component => {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
makeRefCollection(collection, count) {
|
||||||
|
const diff = Math.abs(collection.length - count);
|
||||||
|
|
||||||
|
if (collection.length < count) {
|
||||||
|
const fill = Array.apply(null, new Array(diff)).map(() => React.createRef());
|
||||||
|
collection.splice.apply(collection, [collection.length, diff, ...fill]);
|
||||||
|
} else if (collection.length > count) {
|
||||||
|
collection.splice(collection.length - diff, diff);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async reflowChildren() {
|
async reflowChildren() {
|
||||||
// No child components
|
// No child components
|
||||||
if (this.children === undefined) {
|
if (this.children === undefined) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const reflowed = await Promise.all(this.children.map(c => c.doReflow()));
|
const reflowed = await Promise.all(this.children.map(c => c.current.doReflow()));
|
||||||
|
|
||||||
return reflowed.reduce((memo, value) => memo || value, false);
|
return reflowed.reduce((memo, value) => memo || value, false);
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user