diff --git a/src/components/Render/index.js b/src/components/Render/index.js
index 3aadb09..291faad 100644
--- a/src/components/Render/index.js
+++ b/src/components/Render/index.js
@@ -1,7 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
-import PlaceholderIcon from 'react-feather/dist/icons/file-text';
+import SVG from 'rendering/SVG';
+import Text from 'rendering/Text';
import style from './style.module.css';
@@ -13,7 +14,7 @@ class Render extends React.PureComponent {
svgContainer = React.createRef()
- provideSVGData() {
+ provideSVGData = () => {
if (!this.svgContainer.current) {
return;
}
@@ -26,23 +27,14 @@ class Render extends React.PureComponent {
});
}
- componentDidMount() {
- this.provideSVGData();
- }
-
- componentDidUpdate() {
- this.provideSVGData();
- }
-
render() {
const { expr } = this.props;
- // eslint-disable-next-line no-console
- console.log('Render:', this.constructor.name, expr);
-
// Demo rendering for now
return
-
+
;
}
}
diff --git a/src/rendering/SVG/index.js b/src/rendering/SVG/index.js
new file mode 100644
index 0000000..4db45d6
--- /dev/null
+++ b/src/rendering/SVG/index.js
@@ -0,0 +1,71 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import * as style from './style';
+
+const namespaceProps = {
+ 'xmlns': 'http://www.w3.org/2000/svg',
+ 'xmlns:cc': 'http://creativecommons.org/ns#',
+ 'xmlns:rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
+};
+/* eslint-disable max-len */
+const metadata = `
+
+
+
+
+
+
+
+`;
+/* eslint-enable max-len */
+
+class SVG extends React.PureComponent {
+ static propTypes = {
+ onReflow: PropTypes.func,
+ children: PropTypes.node,
+ padding: PropTypes.number
+ }
+
+ static defaultProps = {
+ padding: 10
+ }
+
+ state = {
+ width: 0,
+ height: 0
+ }
+
+ handleReflow = box => {
+ const { padding } = this.props;
+
+ this.setState({
+ width: Math.round(box.width + 2 * padding),
+ height: Math.round(box.height + 2 * padding)
+ }, () => this.props.onReflow(this));
+ }
+
+ render() {
+ const { width, height } = this.state;
+ const { padding, children } = this.props;
+
+ const svgProps = {
+ width,
+ height,
+ viewBox: [0, 0, width, height].join(' '),
+ style: style.image,
+ ...namespaceProps
+ };
+
+ return ;
+ }
+}
+
+export default SVG;
diff --git a/src/rendering/SVG/style.js b/src/rendering/SVG/style.js
new file mode 100644
index 0000000..12cf68b
--- /dev/null
+++ b/src/rendering/SVG/style.js
@@ -0,0 +1,5 @@
+import { white } from 'rendering/style';
+
+export const image = {
+ backgroundColor: white
+};
diff --git a/src/rendering/Text/index.js b/src/rendering/Text/index.js
new file mode 100644
index 0000000..0b446fd
--- /dev/null
+++ b/src/rendering/Text/index.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import * as style from './style';
+
+class Text extends React.PureComponent {
+ static propTypes = {
+ quoted: PropTypes.bool,
+ onReflow: PropTypes.func,
+ children: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.node),
+ PropTypes.node
+ ]).isRequired
+ }
+
+ state = {
+ transform: ''
+ }
+
+ textRef = React.createRef()
+
+ componentDidMount() {
+ this.reflow();
+ }
+
+ componentDidUpdate() {
+ this.reflow();
+ }
+
+ reflow() {
+ const box = this.textRef.current.getBBox();
+ const transform = `translate(${ -box.x } ${ -box.y })`;
+
+ if (transform === this.state.transform) {
+ return; // No update required
+ }
+
+ this.setState({ transform }, () => this.props.onReflow(box));
+ }
+
+ renderContent() {
+ const { children, quoted } = this.props;
+
+ if (!quoted) {
+ return children;
+ }
+
+ return <>
+ “
+ { children }
+ ”
+ >;
+ }
+
+ render() {
+ const { transform } = this.state;
+
+ const textProps = {
+ style: style.text,
+ transform,
+ ref: this.textRef
+ };
+
+ return
+ { this.renderContent() }
+ ;
+ }
+}
+
+export default Text;
diff --git a/src/rendering/Text/style.js b/src/rendering/Text/style.js
new file mode 100644
index 0000000..514c0a3
--- /dev/null
+++ b/src/rendering/Text/style.js
@@ -0,0 +1,8 @@
+import { fontSize, fontFamily, grey } from 'rendering/style';
+
+export const text = {
+ fontSize, fontFamily
+};
+export const quote = {
+ fill: grey
+};
diff --git a/src/rendering/style.js b/src/rendering/style.js
new file mode 100644
index 0000000..2f896a0
--- /dev/null
+++ b/src/rendering/style.js
@@ -0,0 +1,20 @@
+// Styles are in JS instead of CSS so they will be inlined as attributes
+// instead of served as a CSS file. This is so styles are included in
+// downloaded SVG files.
+
+export const green = '#bada55';
+export const brown = '#6b6659';
+export const tan = '#cbcbba';
+export const black = '#000';
+export const grey = '#908c83';
+export const white = '#fff';
+export const blue = '#dae9e5';
+
+export const fontFamily = 'Arial';
+export const fontSize = '16px';
+export const fontSizeSmall = '12px';
+
+export const strokeBase = {
+ strokeWidth: '2px',
+ stroke: black
+};