Adding a layout pass to SVG image components
text nodes are the only elements that need to be "measured". The dimensions of all other image components can be determined based on the dimensions of their children. This adds a pre-rendering pass to work out dimensions so multiple renders don't need to happen
This commit is contained in:
@@ -22,8 +22,8 @@ exports[`App removing rendered expression 1`] = `
|
||||
<LoadNamespace(FormActions) />
|
||||
</LoadNamespace(Form)>
|
||||
<Render
|
||||
data="LAYOUT(PARSED(test expression))"
|
||||
onRender={[Function]}
|
||||
parsed="PARSED(test expression)"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
@@ -139,8 +139,8 @@ exports[`App rendering an expression 3`] = `
|
||||
<LoadNamespace(FormActions) />
|
||||
</LoadNamespace(Form)>
|
||||
<Render
|
||||
data="LAYOUT(PARSED(test expression))"
|
||||
onRender={[Function]}
|
||||
parsed="PARSED(test expression)"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
@@ -167,8 +167,8 @@ exports[`App rendering image details 1`] = `
|
||||
<LoadNamespace(FormActions) />
|
||||
</LoadNamespace(Form)>
|
||||
<Render
|
||||
data="LAYOUT(PARSED(test expression))"
|
||||
onRender={[Function]}
|
||||
parsed="PARSED(test expression)"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
@@ -201,8 +201,8 @@ exports[`App rendering image details 2`] = `
|
||||
/>
|
||||
</LoadNamespace(Form)>
|
||||
<Render
|
||||
data="LAYOUT(PARSED(test expression))"
|
||||
onRender={[Function]}
|
||||
parsed="PARSED(test expression)"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
@@ -73,13 +73,13 @@ class App extends React.PureComponent {
|
||||
`syntax/${ syntax }`
|
||||
);
|
||||
|
||||
const parsed = syntaxModule.parse(expr);
|
||||
const exprData = syntaxModule.layout(syntaxModule.parse(expr));
|
||||
|
||||
this.setState({
|
||||
loading: false,
|
||||
render: {
|
||||
syntax,
|
||||
parsed,
|
||||
exprData,
|
||||
Component: syntaxModule.Render
|
||||
}
|
||||
});
|
||||
@@ -119,7 +119,7 @@ class App extends React.PureComponent {
|
||||
imageDetails,
|
||||
render: {
|
||||
syntax: renderSyntax,
|
||||
parsed,
|
||||
exprData,
|
||||
Component
|
||||
}
|
||||
} = this.state;
|
||||
@@ -137,7 +137,7 @@ class App extends React.PureComponent {
|
||||
};
|
||||
const renderProps = {
|
||||
onRender: this.handleSvg,
|
||||
parsed
|
||||
data: exprData
|
||||
};
|
||||
|
||||
const doRender = renderSyntax === syntax;
|
||||
|
||||
@@ -6,6 +6,7 @@ import { App } from 'components/App';
|
||||
|
||||
jest.mock('syntax/js', () => ({
|
||||
parse: expr => `PARSED(${ expr })`,
|
||||
layout: parsed => `LAYOUT(${ parsed })`,
|
||||
Render: () => ''
|
||||
}));
|
||||
|
||||
|
||||
@@ -28,13 +28,21 @@ const render = (data, extraProps) => {
|
||||
|
||||
class Render extends React.PureComponent {
|
||||
static propTypes = {
|
||||
parsed: PropTypes.object.isRequired,
|
||||
data: PropTypes.object.isRequired,
|
||||
onRender: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
svgContainer = React.createRef()
|
||||
|
||||
provideSVGData = () => {
|
||||
componentDidMount() {
|
||||
this.provideSVGData();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.provideSVGData();
|
||||
}
|
||||
|
||||
provideSVGData() {
|
||||
if (!this.svgContainer.current) {
|
||||
return;
|
||||
}
|
||||
@@ -48,10 +56,10 @@ class Render extends React.PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { parsed } = this.props;
|
||||
const { data } = this.props;
|
||||
|
||||
return <div className={ style.render } ref={ this.svgContainer }>
|
||||
{ render(parsed, { onReflow: this.provideSVGData }) }
|
||||
{ render(data, { onReflow: this.provideSVGData }) }
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user