Updating FormActions to use hooks

This commit is contained in:
Jeff Avallone 2019-03-28 07:12:03 -04:00
parent 97878c3881
commit 3b07ed2ab5
4 changed files with 48 additions and 301 deletions

View File

@ -20,7 +20,7 @@ exports[`App removing rendered expression 1`] = `
}"
>
<span
data-component="withI18nextTranslation(FormActions)"
data-component="FormActions"
data-props="{}"
/>
</span>
@ -145,7 +145,7 @@ exports[`App rendering an expression 3`] = `
}"
>
<span
data-component="withI18nextTranslation(FormActions)"
data-component="FormActions"
data-props="{}"
/>
</span>

View File

@ -8,168 +8,6 @@ exports[`FormActions rendering 1`] = `
</DocumentFragment>
`;
exports[`FormActions rendering download links 1`] = `
<DocumentFragment>
<ul
class="actions"
>
<li>
<a
download="image.png"
href="http://example.com/image.png"
type="image/png"
>
<span
data-component="Download"
data-props="{}"
/>
TRANSLATE(Example PNG Link)
</a>
</li>
<li>
<a
download="image.svg"
href="http://example.com/image.svg"
type="image/svg+xml"
>
<span
data-component="Download"
data-props="{}"
/>
TRANSLATE(Example SVG Link)
</a>
</li>
</ul>
</DocumentFragment>
`;
exports[`FormActions rendering download links with data after mounting 1`] = `
<DocumentFragment>
<ul
class="actions"
>
<li>
<a
href="http://example.com"
>
<span
data-component="Link"
data-props="{}"
/>
<span
data-component="Trans"
data-props="{}"
>
Permalink
</span>
</a>
</li>
</ul>
</DocumentFragment>
`;
exports[`FormActions rendering download links with data after mounting 2`] = `
<DocumentFragment>
<ul
class="actions"
>
<li>
<a
download="image.png"
href="http://example.com/image.png"
type="image/png"
>
<span
data-component="Download"
data-props="{}"
/>
TRANSLATE(Example PNG Link)
</a>
</li>
<li>
<a
download="image.svg"
href="http://example.com/image.svg"
type="image/svg+xml"
>
<span
data-component="Download"
data-props="{}"
/>
TRANSLATE(Example SVG Link)
</a>
</li>
<li>
<a
href="http://example.com"
>
<span
data-component="Link"
data-props="{}"
/>
<span
data-component="Trans"
data-props="{}"
>
Permalink
</span>
</a>
</li>
</ul>
</DocumentFragment>
`;
exports[`FormActions rendering download links with data after mounting 3`] = `
<DocumentFragment>
<ul
class="actions"
>
<li>
<a
download="image.png"
href="http://example.com/image.png"
type="image/png"
>
<span
data-component="Download"
data-props="{}"
/>
TRANSLATE(Example PNG Link)
</a>
</li>
<li>
<a
download="image.svg"
href="http://example.com/image.svg"
type="image/svg+xml"
>
<span
data-component="Download"
data-props="{}"
/>
TRANSLATE(Example SVG Link)
</a>
</li>
<li>
<a
href="http://example.com"
>
<span
data-component="Link"
data-props="{}"
/>
<span
data-component="Trans"
data-props="{}"
>
Permalink
</span>
</a>
</li>
</ul>
</DocumentFragment>
`;
exports[`FormActions rendering with a permalink 1`] = `
<DocumentFragment>
<ul

View File

@ -1,6 +1,6 @@
import React from 'react';
import React, { useState, useCallback, useEffect } from 'react';
import PropTypes from 'prop-types';
import { withTranslation, Trans } from 'react-i18next';
import { useTranslation, Trans } from 'react-i18next';
import DownloadIcon from 'react-feather/dist/icons/download';
import LinkIcon from 'react-feather/dist/icons/link';
@ -9,89 +9,52 @@ import style from './style.module.css';
import { createPngLink, createSvgLink } from './links';
class FormActions extends React.PureComponent {
static propTypes = {
permalinkUrl: PropTypes.string,
imageDetails: PropTypes.shape({
svg: PropTypes.string,
width: PropTypes.number,
height: PropTypes.number
}),
t: PropTypes.func.isRequired
}
const downloadLink = (link, t) => {
const { url, filename, type, label } = link;
return <li>
<a href={ url } download={ filename } type={ type }>
<DownloadIcon />{ t(label) }
</a>
</li>;
};
state = {
svgLink: null,
pngLink: null
}
const FormActions = ({
permalinkUrl,
imageDetails
}) => {
const { t } = useTranslation();
const [svgLink, setSvgLink] = useState(null);
const [pngLink, setPngLink] = useState(null);
componentDidMount() {
const { imageDetails } = this.props;
const generateDownloadLinks = useCallback(async () => {
const { svg, width, height } = imageDetails;
setSvgLink(await createSvgLink({ svg }));
setPngLink(await createPngLink({ svg, width, height }));
}, [setSvgLink, setPngLink, imageDetails]);
useEffect(() => {
if (imageDetails && imageDetails.svg) {
this.generateDownloadLinks();
generateDownloadLinks();
}
}
}, [imageDetails]);
componentDidUpdate(prevProps) {
const { imageDetails } = this.props;
const { imageDetails: prevImageDetails } = prevProps;
return <ul className={ style.actions }>
{ pngLink && downloadLink(pngLink, t) }
{ svgLink && downloadLink(svgLink, t) }
{ permalinkUrl && <li>
<a href={ permalinkUrl }><LinkIcon /><Trans>Permalink</Trans></a>
</li> }
</ul>;
};
if (!imageDetails) {
this.setState({ svgLink: null, pngLink: null });
return;
}
FormActions.propTypes = {
permalinkUrl: PropTypes.string,
imageDetails: PropTypes.shape({
svg: PropTypes.string,
width: PropTypes.number,
height: PropTypes.number
})
};
if (!prevImageDetails) {
this.generateDownloadLinks();
return;
}
if (imageDetails.svg !== prevImageDetails.svg
|| imageDetails.width !== prevImageDetails.width
|| imageDetails.height !== prevImageDetails.height) {
this.generateDownloadLinks();
return;
}
}
async generateDownloadLinks() {
const { imageDetails: { svg, width, height } } = this.props;
this.setState({
svgLink: await createSvgLink({ svg }),
pngLink: await createPngLink({ svg, width, height })
});
}
downloadLink({ url, filename, type, label }) {
const { t } = this.props;
return <li>
<a href={ url } download={ filename } type={ type }>
<DownloadIcon />{ t(label) }
</a>
</li>;
}
render() {
const {
permalinkUrl
} = this.props;
const {
svgLink,
pngLink
} = this.state;
return <ul className={ style.actions }>
{ pngLink && this.downloadLink(pngLink) }
{ svgLink && this.downloadLink(svgLink) }
{ permalinkUrl && <li>
<a href={ permalinkUrl }><LinkIcon /><Trans>Permalink</Trans></a>
</li> }
</ul>;
}
}
export { FormActions };
export default withTranslation()(FormActions);
export default FormActions;

View File

@ -9,8 +9,7 @@ jest.mock('react-feather/dist/icons/link', () =>
import React from 'react';
import { render } from 'react-testing-library';
import { mockT } from 'i18n';
import { FormActions } from 'components/FormActions';
import FormActions from 'components/FormActions';
import { createPngLink, createSvgLink } from './links';
createPngLink.mockResolvedValue({
@ -29,68 +28,15 @@ createSvgLink.mockResolvedValue({
describe('FormActions', () => {
test('rendering', () => {
const { asFragment } = render(
<FormActions t={ mockT } />
<FormActions/>
);
expect(asFragment()).toMatchSnapshot();
});
test('rendering with a permalink', () => {
const { asFragment } = render(
<FormActions permalinkUrl="http://example.com" t={ mockT } />
<FormActions permalinkUrl="http://example.com" />
);
expect(asFragment()).toMatchSnapshot();
});
test('rendering download links', async () => {
const imageDetails = {
svg: 'test image',
width: 10,
height: 20
};
const { asFragment } = render(
<FormActions imageDetails={ imageDetails } t={ mockT } />
);
// Give a beat for mocked promises to resolve
await new Promise(resolve => setTimeout(resolve));
expect(asFragment()).toMatchSnapshot();
});
test('rendering download links with data after mounting', async () => {
const { asFragment, rerender } = render(
<FormActions t={ mockT } />
);
rerender(
<FormActions permalinkUrl="http://example.com" t={ mockT } />
);
expect(asFragment()).toMatchSnapshot();
rerender(
<FormActions
permalinkUrl="http://example.com"
imageDetails={ { svg: 'test-image' } }
t={ mockT } />
);
// Give a beat for mocked promises to resolve
await new Promise(resolve => setTimeout(resolve));
expect(asFragment()).toMatchSnapshot();
rerender(
<FormActions
permalinkUrl="http://example.com"
imageDetails={ { svg: 'test-image', width: 10, height: 20 } }
t={ mockT } />
);
// Give a beat for mocked promises to resolve
await new Promise(resolve => setTimeout(resolve));
expect(asFragment()).toMatchSnapshot();
});
});