diff --git a/src/components/SectionSearchLinks/SectionSearchLinks.js b/src/components/SectionSearchLinks/SectionSearchLinks.js
deleted file mode 100644
index 538e11b1..00000000
--- a/src/components/SectionSearchLinks/SectionSearchLinks.js
+++ /dev/null
@@ -1,86 +0,0 @@
-import React from 'react';
-import { string, arrayOf, shape, node, oneOf } from 'prop-types';
-import classNames from 'classnames';
-import { NamedLink } from '../../components';
-
-import css from './SectionSearchLinks.css';
-
-const SearchLink = props => {
- const { linksPerRow, imageUrl, imageAltText, searchQuery, text } = props;
- const classes = classNames(css.link, {
- [css.link2Columns]: linksPerRow === 2,
- [css.link3Columns]: linksPerRow === 3,
- });
- return (
-
-
-
-

-
-
- {text}
-
- );
-};
-
-const SectionSearchLinks = props => {
- const {
- rootClassName,
- className,
- linksPerRow,
- links,
- heading,
- subHeading,
- headingRootClassName,
- subHeadingRootClassName,
- } = props;
- const classes = classNames(rootClassName || css.root, className);
- const headingClasses = headingRootClassName || css.heading;
- const subHeadingClasses = subHeadingRootClassName || css.subHeading;
- return (
-
- {heading ?
{heading}
: null}
- {subHeading ?
{subHeading}
: null}
-
- {links.map(link => (
-
- ))}
-
-
- );
-};
-
-SectionSearchLinks.defaultProps = {
- rootClassName: null,
- className: null,
- heading: null,
- subHeading: null,
- headingRootClassName: null,
- subHeadingRootClassName: null,
-};
-
-SectionSearchLinks.propTypes = {
- rootClassName: string,
- className: string,
-
- linksPerRow: oneOf([2, 3]).isRequired,
- links: arrayOf(
- shape({
- imageUrl: string.isRequired,
- imageAltText: string.isRequired,
- searchQuery: string.isRequired,
- text: node.isRequired,
- })
- ).isRequired,
-
- // Styles are defined with the assumption that either both the
- // heading and the subHeading are given, or neither of them are. If
- // only one of them is given, the margins most likely won't make
- // sense.
- heading: node,
- subHeading: node,
- headingRootClassName: string,
- subHeadingRootClassName: string,
-};
-
-export default SectionSearchLinks;
diff --git a/src/components/SectionSearchLinks/SectionSearchLinks.css b/src/components/SectionThumbnailLinks/SectionThumbnailLinks.css
similarity index 100%
rename from src/components/SectionSearchLinks/SectionSearchLinks.css
rename to src/components/SectionThumbnailLinks/SectionThumbnailLinks.css
diff --git a/src/components/SectionSearchLinks/SectionSearchLinks.example.js b/src/components/SectionThumbnailLinks/SectionThumbnailLinks.example.js
similarity index 61%
rename from src/components/SectionSearchLinks/SectionSearchLinks.example.js
rename to src/components/SectionThumbnailLinks/SectionThumbnailLinks.example.js
index 85fc5a36..a3b93fb9 100644
--- a/src/components/SectionSearchLinks/SectionSearchLinks.example.js
+++ b/src/components/SectionThumbnailLinks/SectionThumbnailLinks.example.js
@@ -1,22 +1,22 @@
-import SectionSearchLinks from './SectionSearchLinks';
+import SectionThumbnailLinks from './SectionThumbnailLinks';
const imageAltText = 'styleguide alt text';
-export const TwoLinksWithHeadings = {
- component: SectionSearchLinks,
+export const TwoNamedLinksWithHeadings = {
+ component: SectionThumbnailLinks,
props: {
linksPerRow: 2,
links: [
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?1',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?1' } },
text: 'Link 1',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?2',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?2' } },
text: 'Link 2',
},
],
@@ -26,27 +26,27 @@ export const TwoLinksWithHeadings = {
group: 'sections',
};
-export const ThreeLinksWithHeadings = {
- component: SectionSearchLinks,
+export const ThreeExternalLinksWithHeadings = {
+ component: SectionThumbnailLinks,
props: {
linksPerRow: 3,
links: [
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?1',
+ linkProps: { type: 'ExternalLink', href: 'http://example.com/1' },
text: 'Link 1',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?2',
+ linkProps: { type: 'ExternalLink', href: 'http://example.com/2' },
text: 'Link 2',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?3',
+ linkProps: { type: 'ExternalLink', href: 'http://example.com/3' },
text: 'Link 3',
},
],
@@ -57,32 +57,32 @@ export const ThreeLinksWithHeadings = {
};
export const FourLinks = {
- component: SectionSearchLinks,
+ component: SectionThumbnailLinks,
props: {
linksPerRow: 2,
links: [
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?1',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?1' } },
text: 'Link 1 with quite a long text that tests how the items below align',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?2',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?2' } },
text: 'Link 2',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?3',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?3' } },
text: 'Link 3',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?4',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?4' } },
text: 'Link 4',
},
],
@@ -91,44 +91,45 @@ export const FourLinks = {
};
export const SixLinks = {
- component: SectionSearchLinks,
+ component: SectionThumbnailLinks,
props: {
linksPerRow: 3,
links: [
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?1',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?1' } },
text: 'Link 1',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?2' } },
searchQuery: '?2',
text: 'Link 2',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?3',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?3' } },
text: 'Link 3',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?4',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?4' } },
text: 'Link 4',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?5',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?5' } },
text: 'Link 5',
},
{
imageUrl: 'http://lorempixel.com/648/448/',
imageAltText,
- searchQuery: '?6',
+ linkProps: { type: 'NamedLink', name: 'SearchPage', to: { search: '?6' } },
text: 'Link 6',
},
],
diff --git a/src/components/SectionThumbnailLinks/SectionThumbnailLinks.js b/src/components/SectionThumbnailLinks/SectionThumbnailLinks.js
new file mode 100644
index 00000000..65a2bbb0
--- /dev/null
+++ b/src/components/SectionThumbnailLinks/SectionThumbnailLinks.js
@@ -0,0 +1,129 @@
+import React from 'react';
+import { string, arrayOf, shape, node, oneOf, oneOfType } from 'prop-types';
+import classNames from 'classnames';
+import { ExternalLink, NamedLink } from '../../components';
+
+import css from './SectionThumbnailLinks.css';
+
+const ThumbnailLink = props => {
+ const {
+ className,
+ rootClassName,
+ imageWrapperClassName,
+ linksPerRow,
+ imageUrl,
+ imageAltText,
+ linkProps,
+ text,
+ } = props;
+ const { type, name, to, href } = linkProps;
+ const classes = classNames(rootClassName || css.link, className, {
+ [css.link2Columns]: linksPerRow === 2,
+ [css.link3Columns]: linksPerRow === 3,
+ });
+ const imageWrapperClasses = classNames(css.imageWrapper, imageWrapperClassName);
+
+ const LinkComponentProps = type === 'NamedLink' ? { name, to } : { href };
+ const LinkComponent = type === 'NamedLink' ? NamedLink : ExternalLink;
+
+ return (
+
+
+
+

+
+
+ {text}
+
+ );
+};
+
+const SectionThumbnailLinks = props => {
+ const {
+ rootClassName,
+ className,
+ linksPerRow,
+ links,
+ heading,
+ subHeading,
+ headingRootClassName,
+ subHeadingRootClassName,
+ linkClassName,
+ linkRootClassName,
+ imageWrapperClassName,
+ } = props;
+ const classes = classNames(rootClassName || css.root, className);
+ const headingClasses = headingRootClassName || css.heading;
+ const subHeadingClasses = subHeadingRootClassName || css.subHeading;
+ return (
+
+ {heading ?
{heading}
: null}
+ {subHeading ?
{subHeading}
: null}
+
+ {links.map((link, i) => (
+
+ ))}
+
+
+ );
+};
+
+SectionThumbnailLinks.defaultProps = {
+ rootClassName: null,
+ className: null,
+ heading: null,
+ subHeading: null,
+ headingRootClassName: null,
+ subHeadingRootClassName: null,
+ imageWrapperClassName: null,
+};
+
+const namedLinkShape = shape({
+ type: oneOf(['NamedLink']).isRequired,
+ name: string.isRequired,
+ to: shape({
+ search: string,
+ hash: string,
+ }),
+});
+
+const externalLinkShape = shape({
+ type: oneOf(['ExternalLink']).isRequired,
+ href: string.isRequired,
+});
+
+SectionThumbnailLinks.propTypes = {
+ rootClassName: string,
+ className: string,
+
+ linksPerRow: oneOf([2, 3]).isRequired,
+ links: arrayOf(
+ shape({
+ imageUrl: string.isRequired,
+ imageAltText: string.isRequired,
+ linkProps: oneOfType([namedLinkShape, externalLinkShape]).isRequired,
+ text: node.isRequired,
+ })
+ ).isRequired,
+
+ // Styles are defined with the assumption that either both the
+ // heading and the subHeading are given, or neither of them are. If
+ // only one of them is given, the margins most likely won't make
+ // sense.
+ heading: node,
+ subHeading: node,
+ headingRootClassName: string,
+ subHeadingRootClassName: string,
+ linkClassName: string,
+ linkRootClassName: string,
+ imageWrapperClassName: string,
+};
+
+export default SectionThumbnailLinks;
diff --git a/src/components/index.js b/src/components/index.js
index d0d271bc..98955b6a 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -98,7 +98,7 @@ export { default as SearchResultsPanel } from './SearchResultsPanel/SearchResult
export { default as SectionHero } from './SectionHero/SectionHero';
export { default as SectionHowItWorks } from './SectionHowItWorks/SectionHowItWorks';
export { default as SectionLocations } from './SectionLocations/SectionLocations';
-export { default as SectionSearchLinks } from './SectionSearchLinks/SectionSearchLinks';
+export { default as SectionThumbnailLinks } from './SectionThumbnailLinks/SectionThumbnailLinks';
export { default as SelectField } from './SelectField/SelectField';
export { default as SelectSingleFilter } from './SelectSingleFilter/SelectSingleFilter';
export {
diff --git a/src/examples.js b/src/examples.js
index 9a35f297..5f705ca7 100644
--- a/src/examples.js
+++ b/src/examples.js
@@ -40,7 +40,7 @@ import * as PaginationLinks from './components/PaginationLinks/PaginationLinks.e
import * as ResponsiveImage from './components/ResponsiveImage/ResponsiveImage.example';
import * as ReviewRating from './components/ReviewRating/ReviewRating.example';
import * as Reviews from './components/Reviews/Reviews.example';
-import * as SectionSearchLinks from './components/SectionSearchLinks/SectionSearchLinks.example';
+import * as SectionThumbnailLinks from './components/SectionThumbnailLinks/SectionThumbnailLinks.example';
import * as SelectField from './components/SelectField/SelectField.example';
import * as StripeBankAccountTokenInputField from './components/StripeBankAccountTokenInputField/StripeBankAccountTokenInputField.example';
import * as TabNav from './components/TabNav/TabNav.example';
@@ -124,7 +124,7 @@ export {
ReviewForm,
ReviewRating,
Reviews,
- SectionSearchLinks,
+ SectionThumbnailLinks,
SelectField,
SendMessageForm,
SignupForm,