Adding semi-functional rendering demo of app
This commit is contained in:
parent
0606325d6d
commit
a4450b34b3
@ -71,6 +71,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.2.2",
|
"@babel/core": "^7.2.2",
|
||||||
|
"@ungap/url-search-params": "^0.1.2",
|
||||||
"babel-core": "^7.0.0-bridge.0",
|
"babel-core": "^7.0.0-bridge.0",
|
||||||
"babel-jest": "^23.6.0",
|
"babel-jest": "^23.6.0",
|
||||||
"babel-preset-gatsby": "^0.1.6",
|
"babel-preset-gatsby": "^0.1.6",
|
||||||
|
5
src/components/App/context.js
Normal file
5
src/components/App/context.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const AppContext = React.createContext();
|
||||||
|
|
||||||
|
export default AppContext;
|
161
src/components/App/index.js
Normal file
161
src/components/App/index.js
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import URLSearchParams from '@ungap/url-search-params';
|
||||||
|
|
||||||
|
import AppContext from 'components/App/context';
|
||||||
|
import Form from 'components/Form';
|
||||||
|
import Loader from 'components/Loader';
|
||||||
|
import Message from 'components/Message';
|
||||||
|
import SVG from 'components/SVG';
|
||||||
|
|
||||||
|
const toUrl = params => new URLSearchParams(params).toString();
|
||||||
|
|
||||||
|
const readURLHash = () => {
|
||||||
|
const query = document.location.hash.slice(1);
|
||||||
|
const params = new URLSearchParams(query);
|
||||||
|
|
||||||
|
if (params.get('syntax')) {
|
||||||
|
return {
|
||||||
|
syntax: params.get('syntax'),
|
||||||
|
expr: params.get('expr')
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// Assuming old-style URL
|
||||||
|
return {
|
||||||
|
syntax: 'js',
|
||||||
|
expr: query || ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createSvgLink = async ({ svg }) => {
|
||||||
|
try {
|
||||||
|
const type = 'image/svg+xml';
|
||||||
|
const blob = new Blob([svg], { type });
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: URL.createObjectURL(blob),
|
||||||
|
label: 'Download SVG',
|
||||||
|
filename: 'image.svg',
|
||||||
|
type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e); // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createPngLink = async ({ svg, width, height }) => {
|
||||||
|
try {
|
||||||
|
const type = 'image/png';
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
const loader = new Image();
|
||||||
|
|
||||||
|
loader.width = canvas.width = Number(width) * 2;
|
||||||
|
loader.height = canvas.height = Number(height) * 2;
|
||||||
|
|
||||||
|
await new Promise(resolve => {
|
||||||
|
loader.onload = resolve;
|
||||||
|
loader.src = 'data:image/svg+xml,' + encodeURIComponent(svg);
|
||||||
|
});
|
||||||
|
|
||||||
|
context.drawImage(loader, 0, 0, loader.width, loader.height);
|
||||||
|
|
||||||
|
const blob = await new Promise(resolve => canvas.toBlob(resolve, type));
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: URL.createObjectURL(blob),
|
||||||
|
label: 'Download PNG',
|
||||||
|
filename: 'image.png',
|
||||||
|
type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e); // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class App extends React.PureComponent {
|
||||||
|
state={
|
||||||
|
...readURLHash()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
window.addEventListener('hashchange', this.handleHashChange);
|
||||||
|
this.handleHashChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.removeEventListener('hashchange', this.handleHashChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleHashChange = () => {
|
||||||
|
const { expr, syntax } = readURLHash();
|
||||||
|
|
||||||
|
if (!expr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
syntax,
|
||||||
|
expr,
|
||||||
|
permalinkUrl: document.location.toString()
|
||||||
|
});
|
||||||
|
console.log('Render:', syntax, expr); // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
|
||||||
|
handleRetry = event => {
|
||||||
|
event.preventDefault();
|
||||||
|
this.handleHashChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderExpr = ({ expr, syntax }) => {
|
||||||
|
if (expr) {
|
||||||
|
document.location.hash = toUrl({ syntax, expr });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svgData = async ({ svg, width, height }) => {
|
||||||
|
if (svg !== this.state.svg) {
|
||||||
|
this.setState({
|
||||||
|
svg,
|
||||||
|
svgLink: await createSvgLink({ svg }),
|
||||||
|
pngLink: await createPngLink({ svg, width, height })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
svgLink,
|
||||||
|
pngLink,
|
||||||
|
permalinkUrl,
|
||||||
|
expr,
|
||||||
|
syntax
|
||||||
|
} = this.state;
|
||||||
|
const context = {
|
||||||
|
svgLink,
|
||||||
|
pngLink,
|
||||||
|
permalinkUrl,
|
||||||
|
expr,
|
||||||
|
syntax,
|
||||||
|
renderExpr: this.renderExpr,
|
||||||
|
svgData: this.svgData
|
||||||
|
};
|
||||||
|
|
||||||
|
return <AppContext.Provider value={ context }>
|
||||||
|
<Form />
|
||||||
|
|
||||||
|
<Loader />
|
||||||
|
|
||||||
|
<Message type="error" heading="Render Failure">
|
||||||
|
<p>An error occurred while rendering the regular expression.</p>
|
||||||
|
<a href="#retry" onClick={ this.handleRetry }>Retry</a>
|
||||||
|
</Message>
|
||||||
|
|
||||||
|
<SVG />
|
||||||
|
</AppContext.Provider>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
71
src/components/Form/index.js
Normal file
71
src/components/Form/index.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import ExpandIcon from 'react-feather/dist/icons/chevrons-down';
|
||||||
|
|
||||||
|
import style from './style.module.css';
|
||||||
|
|
||||||
|
import AppContext from 'components/App/context';
|
||||||
|
import FormActions from 'components/FormActions';
|
||||||
|
|
||||||
|
const syntaxList = [
|
||||||
|
{ id: 'js', label: 'JavaScript' },
|
||||||
|
{ id: 'pcre', label: 'PCRE' }
|
||||||
|
];
|
||||||
|
|
||||||
|
class Form extends React.PureComponent {
|
||||||
|
static contextType = AppContext
|
||||||
|
|
||||||
|
state = {
|
||||||
|
expr: this.context.expr,
|
||||||
|
syntax: this.context.syntax
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubmit = event => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const { expr, syntax } = this.state;
|
||||||
|
|
||||||
|
this.context.renderExpr({ expr, syntax });
|
||||||
|
}
|
||||||
|
|
||||||
|
handleKeyPress = event => {
|
||||||
|
if (event.charCode === 13 && event.shiftKey) {
|
||||||
|
this.handleSubmit(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChange = event => this.setState({
|
||||||
|
[event.target.name]: event.target.value
|
||||||
|
})
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { expr, syntax } = this.state;
|
||||||
|
|
||||||
|
return <div className={ style.form }>
|
||||||
|
<form onSubmit={ this.handleSubmit }>
|
||||||
|
<textarea
|
||||||
|
name="expr"
|
||||||
|
value={ expr }
|
||||||
|
onKeyPress={ this.handleKeyPress }
|
||||||
|
onChange={ this.handleChange }
|
||||||
|
autoFocus
|
||||||
|
placeholder="Enter regular expression to display"></textarea>
|
||||||
|
<button type="submit">Display</button>
|
||||||
|
<div className={ style.select }>
|
||||||
|
<select
|
||||||
|
name="syntax"
|
||||||
|
value={ syntax }
|
||||||
|
onChange={ this.handleChange } >
|
||||||
|
{ syntaxList.map(({ id, label }) => (
|
||||||
|
<option value={ id } key={ id }>{ label }</option>
|
||||||
|
)) }
|
||||||
|
</select>
|
||||||
|
<ExpandIcon />
|
||||||
|
</div>
|
||||||
|
<FormActions />
|
||||||
|
</form>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Form;
|
49
src/components/Form/style.module.css
Normal file
49
src/components/Form/style.module.css
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
@import url('../../globals.module.css');
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--control-gradient: var(--color-green) var(--gradient-green);
|
||||||
|
--select-height: 2.8rem;
|
||||||
|
--select-width: 12rem;
|
||||||
|
--entry-line-height: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
margin: var(--spacing-margin) 0;
|
||||||
|
overflow: hidden; /* Keep floated content in the box */
|
||||||
|
|
||||||
|
& textarea {
|
||||||
|
display: block;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: var(--entry-line-height);
|
||||||
|
border: 0 none;
|
||||||
|
outline: none;
|
||||||
|
background: var(--color-tan);
|
||||||
|
padding: 0 1rem;
|
||||||
|
margin-bottom: var(--spacing-margin);
|
||||||
|
width: 100% !important; /* "!important" to prevent user changing width */
|
||||||
|
height: calc(3 * var(--entry-line-height));
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: Consolas, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
& textarea::placeholder {
|
||||||
|
color: var(--color-brown);
|
||||||
|
}
|
||||||
|
|
||||||
|
& button {
|
||||||
|
font-size: inherit;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 2.8rem;
|
||||||
|
width: 10rem;
|
||||||
|
border: 0 none;
|
||||||
|
background: var(--control-gradient);
|
||||||
|
color: var(--color-black);
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.select {
|
||||||
|
composes: fancy-select;
|
||||||
|
}
|
38
src/components/FormActions/index.js
Normal file
38
src/components/FormActions/index.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import DownloadIcon from 'react-feather/dist/icons/download';
|
||||||
|
import LinkIcon from 'react-feather/dist/icons/link';
|
||||||
|
|
||||||
|
import style from './style.module.css';
|
||||||
|
|
||||||
|
import AppContext from 'components/App/context';
|
||||||
|
|
||||||
|
class FormActions extends React.PureComponent {
|
||||||
|
static contextType = AppContext
|
||||||
|
|
||||||
|
downloadLink({ url, filename, type, label }) {
|
||||||
|
return <li>
|
||||||
|
<a href={ url } download={ filename } type={ type }>
|
||||||
|
<DownloadIcon />{ label }
|
||||||
|
</a>
|
||||||
|
</li>;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
permalinkUrl,
|
||||||
|
svgLink,
|
||||||
|
pngLink
|
||||||
|
} = this.context;
|
||||||
|
|
||||||
|
return <ul className={ style.actions }>
|
||||||
|
{ pngLink && this.downloadLink(pngLink) }
|
||||||
|
{ svgLink && this.downloadLink(svgLink) }
|
||||||
|
{ permalinkUrl && <li>
|
||||||
|
<a href={ permalinkUrl }><LinkIcon />Permalink</a>
|
||||||
|
</li> }
|
||||||
|
</ul>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FormActions;
|
19
src/components/FormActions/style.module.css
Normal file
19
src/components/FormActions/style.module.css
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
@import url('../../globals.module.css');
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
composes: inline-list with-separator-left;
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
& li {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& svg {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
80
src/components/Loader/__snapshots__/test.js.snap
Normal file
80
src/components/Loader/__snapshots__/test.js.snap
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Loader rendering 1`] = `
|
||||||
|
<Loader>
|
||||||
|
<div
|
||||||
|
className="loader"
|
||||||
|
>
|
||||||
|
<Loader
|
||||||
|
color="currentColor"
|
||||||
|
size="24"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
fill="none"
|
||||||
|
height="24"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<line
|
||||||
|
x1="12"
|
||||||
|
x2="12"
|
||||||
|
y1="2"
|
||||||
|
y2="6"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
x1="12"
|
||||||
|
x2="12"
|
||||||
|
y1="18"
|
||||||
|
y2="22"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
x1="4.93"
|
||||||
|
x2="7.76"
|
||||||
|
y1="4.93"
|
||||||
|
y2="7.76"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
x1="16.24"
|
||||||
|
x2="19.07"
|
||||||
|
y1="16.24"
|
||||||
|
y2="19.07"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
x1="2"
|
||||||
|
x2="6"
|
||||||
|
y1="12"
|
||||||
|
y2="12"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
x1="18"
|
||||||
|
x2="22"
|
||||||
|
y1="12"
|
||||||
|
y2="12"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
x1="4.93"
|
||||||
|
x2="7.76"
|
||||||
|
y1="19.07"
|
||||||
|
y2="16.24"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
x1="16.24"
|
||||||
|
x2="19.07"
|
||||||
|
y1="7.76"
|
||||||
|
y2="4.93"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</Loader>
|
||||||
|
<div
|
||||||
|
className="message"
|
||||||
|
>
|
||||||
|
Loading...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Loader>
|
||||||
|
`;
|
14
src/components/Loader/index.js
Normal file
14
src/components/Loader/index.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import LoaderIcon from 'react-feather/dist/icons/loader';
|
||||||
|
|
||||||
|
import style from './style.module.css';
|
||||||
|
|
||||||
|
const Loader = () => (
|
||||||
|
<div className={ style.loader }>
|
||||||
|
<LoaderIcon />
|
||||||
|
<div className={ style.message }>Loading...</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Loader;
|
43
src/components/Loader/style.module.css
Normal file
43
src/components/Loader/style.module.css
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
@import url('../../globals.module.css');
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: var(--spacing-margin) 0;
|
||||||
|
padding: 2rem;
|
||||||
|
background: var(--color-white);
|
||||||
|
color: var(--color-black);
|
||||||
|
|
||||||
|
& .message {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
& svg {
|
||||||
|
display: block;
|
||||||
|
transform: scaleZ(1); /* Move to separate render layer in Chrome */
|
||||||
|
width: 4rem;
|
||||||
|
height: 4rem;
|
||||||
|
stroke: var(--color-black);
|
||||||
|
animation: loader-spin 1s steps(8) infinite;
|
||||||
|
|
||||||
|
& line:nth-of-type(1) { stroke: color(var(--color-black) alpha(0.75)); }
|
||||||
|
& line:nth-of-type(3) { stroke: color(var(--color-black) alpha(0.50)); }
|
||||||
|
& line:nth-of-type(5) { stroke: color(var(--color-black) alpha(0.25)); }
|
||||||
|
& line:nth-of-type(7) { stroke: color(var(--color-black) alpha(0)); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes loader-spin {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
15
src/components/Loader/test.js
Normal file
15
src/components/Loader/test.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { mount } from 'enzyme';
|
||||||
|
|
||||||
|
import Loader from 'components/Loader';
|
||||||
|
|
||||||
|
describe('Loader', () => {
|
||||||
|
test('rendering', () => {
|
||||||
|
// Using full rendering here since styles for this depend on the structure
|
||||||
|
// of the SVG.
|
||||||
|
const component = mount(
|
||||||
|
<Loader />
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
43
src/components/SVG/index.js
Normal file
43
src/components/SVG/index.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import PlaceholderIcon from 'react-feather/dist/icons/file-text';
|
||||||
|
|
||||||
|
import style from './style.module.css';
|
||||||
|
|
||||||
|
import AppContext from 'components/App/context';
|
||||||
|
|
||||||
|
class SVG extends React.PureComponent {
|
||||||
|
static contextType = AppContext
|
||||||
|
|
||||||
|
svgContainer = React.createRef()
|
||||||
|
|
||||||
|
provideSVGData() {
|
||||||
|
if (!this.svgContainer.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const svg = this.svgContainer.current.querySelector('svg');
|
||||||
|
this.context.svgData({
|
||||||
|
svg: svg.outerHTML,
|
||||||
|
width: svg.getAttribute('width'),
|
||||||
|
height: svg.getAttribute('height')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.provideSVGData();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
this.provideSVGData();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
// Demo rendering for now
|
||||||
|
return <div className={ style.render } ref={ this.svgContainer }>
|
||||||
|
<PlaceholderIcon />
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SVG;
|
15
src/components/SVG/style.module.css
Normal file
15
src/components/SVG/style.module.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@import url('../../globals.module.css');
|
||||||
|
|
||||||
|
.render {
|
||||||
|
width: 100%;
|
||||||
|
background: var(--color-white);
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: auto;
|
||||||
|
margin: var(--spacing-margin) 0;
|
||||||
|
|
||||||
|
& svg {
|
||||||
|
display: block;
|
||||||
|
transform: scaleZ(1); /* Move to separate render layer in Chrome */
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
@ -22,10 +22,6 @@ exports[`Index Page rendering 1`] = `
|
|||||||
</p>
|
</p>
|
||||||
</Message>
|
</Message>
|
||||||
</noscript>
|
</noscript>
|
||||||
<div>
|
<App />
|
||||||
<WithMergedOptions(TransComponent)>
|
|
||||||
Hello world
|
|
||||||
</WithMergedOptions(TransComponent)>
|
|
||||||
</div>
|
|
||||||
</Fragment>
|
</Fragment>
|
||||||
`;
|
`;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'gatsby';
|
import { Link } from 'gatsby';
|
||||||
import { withNamespaces, Trans } from 'react-i18next';
|
|
||||||
|
|
||||||
import Metadata from 'components/Metadata';
|
import Metadata from 'components/Metadata';
|
||||||
import Message from 'components/Message';
|
import Message from 'components/Message';
|
||||||
|
import App from 'components/App';
|
||||||
|
|
||||||
export const IndexPage = () => <>
|
export const IndexPage = () => <>
|
||||||
<Metadata/>
|
<Metadata/>
|
||||||
@ -14,7 +14,7 @@ export const IndexPage = () => <>
|
|||||||
please see the <Link to="/privacy">Privacy Policy</Link>.</p>
|
please see the <Link to="/privacy">Privacy Policy</Link>.</p>
|
||||||
</Message>
|
</Message>
|
||||||
</noscript>
|
</noscript>
|
||||||
<div><Trans>Hello world</Trans></div>
|
<App />
|
||||||
</>;
|
</>;
|
||||||
|
|
||||||
export default withNamespaces()(IndexPage);
|
export default IndexPage;
|
||||||
|
@ -940,6 +940,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.0.32.tgz#0d3cb31022f8427ea58c008af32b80da126ca4e3"
|
resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.0.32.tgz#0d3cb31022f8427ea58c008af32b80da126ca4e3"
|
||||||
integrity sha1-DTyzECL4Qn6ljACK8yuA2hJspOM=
|
integrity sha1-DTyzECL4Qn6ljACK8yuA2hJspOM=
|
||||||
|
|
||||||
|
"@ungap/url-search-params@^0.1.2":
|
||||||
|
version "0.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ungap/url-search-params/-/url-search-params-0.1.2.tgz#8ba8c0527543fe675d1c29ae0a2daca842e8ee4f"
|
||||||
|
integrity sha512-WVk5+lJ+AoNLh2sIDMhnEAgLsVQuI067hWLJCzirErH1GYiy1gs09q4+XZxYWSvdAsslKsaO4q1iXXMx2c72dA==
|
||||||
|
|
||||||
"@webassemblyjs/ast@1.7.11":
|
"@webassemblyjs/ast@1.7.11":
|
||||||
version "1.7.11"
|
version "1.7.11"
|
||||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace"
|
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace"
|
||||||
|
Loading…
Reference in New Issue
Block a user