Compare commits
10 Commits
v1.0.0
...
abutterwor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abe3d03f58 | ||
|
|
7af4b71faa | ||
|
|
7f2c5b32b1 | ||
|
|
6e0f9cf30a | ||
|
|
3dc70a890f | ||
|
|
a37ef7f701 | ||
|
|
a19c762cf7 | ||
|
|
045e28d0ef | ||
|
|
e39ac1ca43 | ||
|
|
2ed1a1aa8c |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
coverage
|
coverage
|
||||||
dist
|
dist
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|||||||
33
README.md
33
README.md
@@ -1,33 +0,0 @@
|
|||||||
# frontend-component-footer
|
|
||||||
|
|
||||||
[](https://travis-ci.org/edx/frontend-component-footer) [](https://coveralls.io/github/edx/frontend-component-footer)
|
|
||||||
[](@edx/frontend-component-footer)
|
|
||||||
[](@edx/frontend-component-footer)
|
|
||||||
[](@edx/frontend-component-footer)
|
|
||||||
[](https://github.com/semantic-release/semantic-release)
|
|
||||||
|
|
||||||
|
|
||||||
frontend-component-footer is a library containing a site footer component for use when building edX frontend applications.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
To install frontend-component-footer into your project:
|
|
||||||
|
|
||||||
```
|
|
||||||
npm i --save @edx/frontend-component-footer
|
|
||||||
```
|
|
||||||
|
|
||||||
The component expects properties specifying the various URLs that are linked in the footer. See the
|
|
||||||
sample app in src/index.jsx for an example of how the SiteFooter component can be specified.
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
Start the dev server
|
|
||||||
```
|
|
||||||
npm i && npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
Build the component.
|
|
||||||
```
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
46
README.rst
Normal file
46
README.rst
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
frontend-component-footer
|
||||||
|
=========================
|
||||||
|
|
||||||
|
|Build Status| |Coveralls| |npm_version| |npm_downloads| |license|
|
||||||
|
|semantic-release|
|
||||||
|
|
||||||
|
frontend-component-footer is a library containing a site footer
|
||||||
|
component for use when building edX frontend applications.
|
||||||
|
|
||||||
|
At this time, this componenet is hard-coded to match the legacy LMS site footer, including all of its links.
|
||||||
|
Note: As implemented, it should really be called the ``frontend-component-lms-footer``.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
To install frontend-component-footer into your project::
|
||||||
|
|
||||||
|
npm i --save @edx/frontend-component-footer
|
||||||
|
|
||||||
|
The component expects properties specifying the various URLs that are
|
||||||
|
linked in the footer. See the sample app in src/index.jsx for an example
|
||||||
|
of how the SiteFooter component can be specified.
|
||||||
|
|
||||||
|
Development
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Start the dev server::
|
||||||
|
|
||||||
|
npm i && npm start
|
||||||
|
|
||||||
|
Build the component::
|
||||||
|
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
.. |Build Status| image:: https://api.travis-ci.org/edx/frontend-component-footer.svg?branch=master
|
||||||
|
:target: https://travis-ci.org/edx/frontend-component-footer
|
||||||
|
.. |Coveralls| image:: https://img.shields.io/coveralls/edx/frontend-component-footer.svg?branch=master
|
||||||
|
:target: https://coveralls.io/github/edx/frontend-component-footer
|
||||||
|
.. |npm_version| image:: https://img.shields.io/npm/v/@edx/frontend-component-footer.svg
|
||||||
|
:target: @edx/frontend-component-footer
|
||||||
|
.. |npm_downloads| image:: https://img.shields.io/npm/dt/@edx/frontend-component-footer.svg
|
||||||
|
:target: @edx/frontend-component-footer
|
||||||
|
.. |license| image:: https://img.shields.io/npm/l/@edx/frontend-component-footer.svg
|
||||||
|
:target: @edx/frontend-component-footer
|
||||||
|
.. |semantic-release| image:: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
|
||||||
|
:target: https://github.com/semantic-release/semantic-release
|
||||||
16
package-lock.json
generated
16
package-lock.json
generated
@@ -21666,6 +21666,16 @@
|
|||||||
"snapdragon": "^0.8.1",
|
"snapdragon": "^0.8.1",
|
||||||
"to-regex": "^3.0.2"
|
"to-regex": "^3.0.2"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"watch": {
|
||||||
|
"version": "0.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz",
|
||||||
|
"integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"exec-sh": "^0.2.0",
|
||||||
|
"minimist": "^1.2.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -24627,9 +24637,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"watch": {
|
"watch": {
|
||||||
"version": "0.18.0",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/watch/-/watch-1.0.2.tgz",
|
||||||
"integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=",
|
"integrity": "sha1-NApxe952Vyb6CqB9ch4BR6VR3ww=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"exec-sh": "^0.2.0",
|
"exec-sh": "^0.2.0",
|
||||||
|
|||||||
@@ -19,7 +19,8 @@
|
|||||||
"start": "NODE_ENV=development BABEL_ENV=development node_modules/.bin/webpack-dev-server --config=config/webpack.dev.config.js --progress",
|
"start": "NODE_ENV=development BABEL_ENV=development node_modules/.bin/webpack-dev-server --config=config/webpack.dev.config.js --progress",
|
||||||
"test": "jest --coverage",
|
"test": "jest --coverage",
|
||||||
"snapshot": "jest --updateSnapshot",
|
"snapshot": "jest --updateSnapshot",
|
||||||
"travis-deploy-once": "travis-deploy-once"
|
"travis-deploy-once": "travis-deploy-once",
|
||||||
|
"watch": "watch 'npm run build' ./src"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -68,6 +69,7 @@
|
|||||||
"source-map-loader": "^0.2.1",
|
"source-map-loader": "^0.2.1",
|
||||||
"style-loader": "^0.20.2",
|
"style-loader": "^0.20.2",
|
||||||
"travis-deploy-once": "^5.0.0",
|
"travis-deploy-once": "^5.0.0",
|
||||||
|
"watch": "^1.0.2",
|
||||||
"webpack": "^4.19.1",
|
"webpack": "^4.19.1",
|
||||||
"webpack-cli": "^3.1.0",
|
"webpack-cli": "^3.1.0",
|
||||||
"webpack-dev-server": "^3.1.9",
|
"webpack-dev-server": "^3.1.9",
|
||||||
@@ -76,7 +78,6 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@edx/paragon": "^3.8.0",
|
"@edx/paragon": "^3.8.0",
|
||||||
"clean-webpack-plugin": "^0.1.19",
|
"clean-webpack-plugin": "^0.1.19",
|
||||||
"copy-webpack-plugin": "^4.6.0",
|
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"prop-types": "^15.5.10",
|
"prop-types": "^15.5.10",
|
||||||
"react": "^16.4.2",
|
"react": "^16.4.2",
|
||||||
|
|||||||
@@ -1,81 +1,112 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import renderer from 'react-test-renderer';
|
import renderer from 'react-test-renderer';
|
||||||
|
import { mount } from 'enzyme';
|
||||||
|
|
||||||
import FooterLogo from '../../../edx-footer.png';
|
import FooterLogo from '../../../edx-footer.png';
|
||||||
import SiteFooter from '../../index';
|
import SiteFooter, { EVENT_NAMES } from './index';
|
||||||
|
|
||||||
|
const completeSiteFooterComponent = mockHandleAllTrackEvents =>
|
||||||
|
(<SiteFooter
|
||||||
|
siteName="example"
|
||||||
|
siteLogo={FooterLogo}
|
||||||
|
marketingSiteBaseUrl="https://www.example.com"
|
||||||
|
supportUrl="https://www.example.com/support"
|
||||||
|
contactUrl="https://www.example.com/contact"
|
||||||
|
openSourceUrl="https://www.example.com/open"
|
||||||
|
termsOfServiceUrl="https://www.example.com/terms-of-service"
|
||||||
|
privacyPolicyUrl="https://www.example.com/privacy-policy"
|
||||||
|
facebookUrl="https://www.facebook.com"
|
||||||
|
twitterUrl="https://www.twitter.com"
|
||||||
|
youTubeUrl="https://www.youtube.com"
|
||||||
|
linkedInUrl="https://www.linkedin.com"
|
||||||
|
googlePlusUrl="https://plus.google.com"
|
||||||
|
redditUrl="https://reddit.com"
|
||||||
|
appleAppStoreUrl="https://store.apple.com"
|
||||||
|
googlePlayUrl="https://play.google.com"
|
||||||
|
handleAllTrackEvents={mockHandleAllTrackEvents}
|
||||||
|
/>);
|
||||||
|
|
||||||
describe('<SiteFooter />', () => {
|
describe('<SiteFooter />', () => {
|
||||||
it('renders correctly', () => {
|
describe('renders correctly', () => {
|
||||||
const tree = renderer
|
it('renders with social and mobile links', () => {
|
||||||
.create(<SiteFooter
|
const mockHandleAllTrackEvents = jest.fn();
|
||||||
siteName="example"
|
const tree = renderer
|
||||||
siteLogo={FooterLogo}
|
.create(completeSiteFooterComponent(mockHandleAllTrackEvents))
|
||||||
marketingSiteBaseUrl="https://www.example.com"
|
.toJSON();
|
||||||
supportUrl="https://www.example.com/support"
|
expect(tree).toMatchSnapshot();
|
||||||
contactUrl="https://www.example.com/contact"
|
});
|
||||||
openSourceUrl="https://www.example.com/open"
|
|
||||||
termsOfServiceUrl="https://www.example.com/terms-of-service"
|
it('does not render social links', () => {
|
||||||
privacyPolicyUrl="https://www.example.com/privacy-policy"
|
const tree = renderer
|
||||||
facebookUrl="https://www.facebook.com"
|
.create(<SiteFooter
|
||||||
twitterUrl="https://www.twitter.com"
|
siteName="example"
|
||||||
youTubeUrl="https://www.youtube.com"
|
siteLogo={FooterLogo}
|
||||||
linkedInUrl="https://www.linkedin.com"
|
marketingSiteBaseUrl="https://www.example.com"
|
||||||
googlePlusUrl="https://plus.google.com"
|
supportUrl="https://www.example.com/support"
|
||||||
redditUrl="https://reddit.com"
|
contactUrl="https://www.example.com/contact"
|
||||||
appleAppStoreUrl="https://store.apple.com"
|
openSourceUrl="https://www.example.com/open"
|
||||||
googlePlayUrl="https://play.google.com"
|
termsOfServiceUrl="https://www.example.com/terms-of-service"
|
||||||
/>)
|
privacyPolicyUrl="https://www.example.com/privacy-policy"
|
||||||
.toJSON();
|
facebookUrl="https://www.facebook.com"
|
||||||
expect(tree).toMatchSnapshot();
|
twitterUrl="https://www.twitter.com"
|
||||||
|
youTubeUrl="https://www.youtube.com"
|
||||||
|
linkedInUrl="https://www.linkedin.com"
|
||||||
|
googlePlusUrl="https://plus.google.com"
|
||||||
|
redditUrl="https://reddit.com"
|
||||||
|
appleAppStoreUrl="https://store.apple.com"
|
||||||
|
googlePlayUrl="https://play.google.com"
|
||||||
|
handleAllTrackEvents={jest.fn()}
|
||||||
|
showSocialLinks={false}
|
||||||
|
/>)
|
||||||
|
.toJSON();
|
||||||
|
expect(tree).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render mobile links', () => {
|
||||||
|
const tree = renderer
|
||||||
|
.create(<SiteFooter
|
||||||
|
siteName="example"
|
||||||
|
siteLogo={FooterLogo}
|
||||||
|
marketingSiteBaseUrl="https://www.example.com"
|
||||||
|
supportUrl="https://www.example.com/support"
|
||||||
|
contactUrl="https://www.example.com/contact"
|
||||||
|
openSourceUrl="https://www.example.com/open"
|
||||||
|
termsOfServiceUrl="https://www.example.com/terms-of-service"
|
||||||
|
privacyPolicyUrl="https://www.example.com/privacy-policy"
|
||||||
|
facebookUrl="https://www.facebook.com"
|
||||||
|
twitterUrl="https://www.twitter.com"
|
||||||
|
youTubeUrl="https://www.youtube.com"
|
||||||
|
linkedInUrl="https://www.linkedin.com"
|
||||||
|
googlePlusUrl="https://plus.google.com"
|
||||||
|
redditUrl="https://reddit.com"
|
||||||
|
appleAppStoreUrl="https://store.apple.com"
|
||||||
|
googlePlayUrl="https://play.google.com"
|
||||||
|
handleAllTrackEvents={jest.fn()}
|
||||||
|
showMobileLinks={false}
|
||||||
|
/>)
|
||||||
|
.toJSON();
|
||||||
|
expect(tree).toMatchSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not render social links', () => {
|
describe('handles analytics', () => {
|
||||||
const tree = renderer
|
it('calls handleAllTrackEvents prop when external links clicked', () => {
|
||||||
.create(<SiteFooter
|
const mockHandleAllTrackEvents = jest.fn();
|
||||||
siteName="example"
|
const footer = mount((completeSiteFooterComponent(mockHandleAllTrackEvents)));
|
||||||
siteLogo={FooterLogo}
|
const externalLinks = footer.find("a[target='_blank']");
|
||||||
marketingSiteBaseUrl="https://www.example.com"
|
|
||||||
supportUrl="https://www.example.com/support"
|
|
||||||
contactUrl="https://www.example.com/contact"
|
|
||||||
openSourceUrl="https://www.example.com/open"
|
|
||||||
termsOfServiceUrl="https://www.example.com/terms-of-service"
|
|
||||||
privacyPolicyUrl="https://www.example.com/privacy-policy"
|
|
||||||
facebookUrl="https://www.facebook.com"
|
|
||||||
twitterUrl="https://www.twitter.com"
|
|
||||||
youTubeUrl="https://www.youtube.com"
|
|
||||||
linkedInUrl="https://www.linkedin.com"
|
|
||||||
googlePlusUrl="https://plus.google.com"
|
|
||||||
redditUrl="https://reddit.com"
|
|
||||||
appleAppStoreUrl="https://store.apple.com"
|
|
||||||
googlePlayUrl="https://play.google.com"
|
|
||||||
showSocialLinks={false}
|
|
||||||
/>)
|
|
||||||
.toJSON();
|
|
||||||
expect(tree).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not render mobile links', () => {
|
expect(externalLinks).toHaveLength(8);
|
||||||
const tree = renderer
|
externalLinks.forEach((externalLink) => {
|
||||||
.create(<SiteFooter
|
const callIndex = mockHandleAllTrackEvents.mock.calls.length;
|
||||||
siteName="example"
|
externalLink.simulate('click');
|
||||||
siteLogo={FooterLogo}
|
expect(mockHandleAllTrackEvents.mock.calls[callIndex]).toEqual([
|
||||||
marketingSiteBaseUrl="https://www.example.com"
|
EVENT_NAMES.FOOTER_LINK,
|
||||||
supportUrl="https://www.example.com/support"
|
{
|
||||||
contactUrl="https://www.example.com/contact"
|
category: 'outbound_link',
|
||||||
openSourceUrl="https://www.example.com/open"
|
label: externalLink.prop('href'),
|
||||||
termsOfServiceUrl="https://www.example.com/terms-of-service"
|
},
|
||||||
privacyPolicyUrl="https://www.example.com/privacy-policy"
|
]);
|
||||||
facebookUrl="https://www.facebook.com"
|
});
|
||||||
twitterUrl="https://www.twitter.com"
|
});
|
||||||
youTubeUrl="https://www.youtube.com"
|
|
||||||
linkedInUrl="https://www.linkedin.com"
|
|
||||||
googlePlusUrl="https://plus.google.com"
|
|
||||||
redditUrl="https://reddit.com"
|
|
||||||
appleAppStoreUrl="https://store.apple.com"
|
|
||||||
googlePlayUrl="https://play.google.com"
|
|
||||||
showMobileLinks={false}
|
|
||||||
/>)
|
|
||||||
.toJSON();
|
|
||||||
expect(tree).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`<SiteFooter /> does not render mobile links 1`] = `
|
exports[`<SiteFooter /> renders correctly does not render mobile links 1`] = `
|
||||||
<footer
|
<footer
|
||||||
aria-label="Page Footer"
|
aria-label="Page Footer"
|
||||||
className="footer d-flex justify-content-center border-top py-3 px-4"
|
className="footer d-flex justify-content-center border-top py-3 px-4"
|
||||||
@@ -180,6 +180,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://www.facebook.com"
|
href="https://www.facebook.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Facebook"
|
title="Facebook"
|
||||||
@@ -187,7 +188,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="fa fa-facebook-square fa-2x"
|
className="fa fa-facebook-square fa-2x"
|
||||||
id="Icon1"
|
id="edx-footer-icon-facebook"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="sr-only"
|
className="sr-only"
|
||||||
@@ -199,6 +200,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://www.twitter.com"
|
href="https://www.twitter.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Twitter"
|
title="Twitter"
|
||||||
@@ -206,7 +208,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="fa fa-twitter-square fa-2x"
|
className="fa fa-twitter-square fa-2x"
|
||||||
id="Icon1"
|
id="edx-footer-icon-twitter"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="sr-only"
|
className="sr-only"
|
||||||
@@ -218,6 +220,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://www.youtube.com"
|
href="https://www.youtube.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Youtube"
|
title="Youtube"
|
||||||
@@ -225,7 +228,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="fa fa-youtube-square fa-2x"
|
className="fa fa-youtube-square fa-2x"
|
||||||
id="Icon1"
|
id="edx-footer-icon-youtube"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="sr-only"
|
className="sr-only"
|
||||||
@@ -237,6 +240,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://www.linkedin.com"
|
href="https://www.linkedin.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="LinkedIn"
|
title="LinkedIn"
|
||||||
@@ -244,7 +248,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="fa fa-linkedin-square fa-2x"
|
className="fa fa-linkedin-square fa-2x"
|
||||||
id="Icon1"
|
id="edx-footer-icon-linkedin"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="sr-only"
|
className="sr-only"
|
||||||
@@ -256,6 +260,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://plus.google.com"
|
href="https://plus.google.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Google+"
|
title="Google+"
|
||||||
@@ -263,7 +268,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="fa fa-google-plus-square fa-2x"
|
className="fa fa-google-plus-square fa-2x"
|
||||||
id="Icon1"
|
id="edx-footer-icon-google"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="sr-only"
|
className="sr-only"
|
||||||
@@ -275,6 +280,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://reddit.com"
|
href="https://reddit.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Reddit"
|
title="Reddit"
|
||||||
@@ -306,7 +312,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
|||||||
</footer>
|
</footer>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<SiteFooter /> does not render social links 1`] = `
|
exports[`<SiteFooter /> renders correctly does not render social links 1`] = `
|
||||||
<footer
|
<footer
|
||||||
aria-label="Page Footer"
|
aria-label="Page Footer"
|
||||||
className="footer d-flex justify-content-center border-top py-3 px-4"
|
className="footer d-flex justify-content-center border-top py-3 px-4"
|
||||||
@@ -486,6 +492,7 @@ exports[`<SiteFooter /> does not render social links 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://store.apple.com"
|
href="https://store.apple.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
@@ -499,6 +506,7 @@ exports[`<SiteFooter /> does not render social links 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://play.google.com"
|
href="https://play.google.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
@@ -524,7 +532,7 @@ exports[`<SiteFooter /> does not render social links 1`] = `
|
|||||||
</footer>
|
</footer>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<SiteFooter /> renders correctly 1`] = `
|
exports[`<SiteFooter /> renders correctly renders with social and mobile links 1`] = `
|
||||||
<footer
|
<footer
|
||||||
aria-label="Page Footer"
|
aria-label="Page Footer"
|
||||||
className="footer d-flex justify-content-center border-top py-3 px-4"
|
className="footer d-flex justify-content-center border-top py-3 px-4"
|
||||||
@@ -704,6 +712,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://www.facebook.com"
|
href="https://www.facebook.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Facebook"
|
title="Facebook"
|
||||||
@@ -711,7 +720,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="fa fa-facebook-square fa-2x"
|
className="fa fa-facebook-square fa-2x"
|
||||||
id="Icon1"
|
id="edx-footer-icon-facebook"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="sr-only"
|
className="sr-only"
|
||||||
@@ -723,6 +732,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://www.twitter.com"
|
href="https://www.twitter.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Twitter"
|
title="Twitter"
|
||||||
@@ -730,7 +740,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="fa fa-twitter-square fa-2x"
|
className="fa fa-twitter-square fa-2x"
|
||||||
id="Icon1"
|
id="edx-footer-icon-twitter"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="sr-only"
|
className="sr-only"
|
||||||
@@ -742,6 +752,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://www.youtube.com"
|
href="https://www.youtube.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Youtube"
|
title="Youtube"
|
||||||
@@ -749,7 +760,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="fa fa-youtube-square fa-2x"
|
className="fa fa-youtube-square fa-2x"
|
||||||
id="Icon1"
|
id="edx-footer-icon-youtube"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="sr-only"
|
className="sr-only"
|
||||||
@@ -761,6 +772,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://www.linkedin.com"
|
href="https://www.linkedin.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="LinkedIn"
|
title="LinkedIn"
|
||||||
@@ -768,7 +780,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="fa fa-linkedin-square fa-2x"
|
className="fa fa-linkedin-square fa-2x"
|
||||||
id="Icon1"
|
id="edx-footer-icon-linkedin"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="sr-only"
|
className="sr-only"
|
||||||
@@ -780,6 +792,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://plus.google.com"
|
href="https://plus.google.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Google+"
|
title="Google+"
|
||||||
@@ -787,7 +800,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="fa fa-google-plus-square fa-2x"
|
className="fa fa-google-plus-square fa-2x"
|
||||||
id="Icon1"
|
id="edx-footer-icon-google"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="sr-only"
|
className="sr-only"
|
||||||
@@ -799,6 +812,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://reddit.com"
|
href="https://reddit.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Reddit"
|
title="Reddit"
|
||||||
@@ -822,6 +836,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://store.apple.com"
|
href="https://store.apple.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
@@ -835,6 +850,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="https://play.google.com"
|
href="https://play.google.com"
|
||||||
|
onClick={[Function]}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -2,7 +2,26 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Hyperlink, Icon } from '@edx/paragon';
|
import { Hyperlink, Icon } from '@edx/paragon';
|
||||||
|
|
||||||
|
const EVENT_NAMES = {
|
||||||
|
FOOTER_LINK: 'edx.bi.footer.link',
|
||||||
|
};
|
||||||
|
|
||||||
class SiteFooter extends React.Component {
|
class SiteFooter extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.externalLinkClickHandler = this.externalLinkClickHandler.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
externalLinkClickHandler(event) {
|
||||||
|
const label = event.currentTarget.getAttribute('href');
|
||||||
|
const eventName = EVENT_NAMES.FOOTER_LINK;
|
||||||
|
const properties = {
|
||||||
|
category: 'outbound_link',
|
||||||
|
label,
|
||||||
|
};
|
||||||
|
this.props.handleAllTrackEvents(eventName, properties);
|
||||||
|
}
|
||||||
|
|
||||||
renderSiteLogo() {
|
renderSiteLogo() {
|
||||||
return (
|
return (
|
||||||
<img src={this.props.siteLogo} alt={`${this.props.siteName} logo`} />
|
<img src={this.props.siteLogo} alt={`${this.props.siteName} logo`} />
|
||||||
@@ -33,32 +52,70 @@ class SiteFooter extends React.Component {
|
|||||||
{/* TODO: Use Paragon HyperLink with Icon. */}
|
{/* TODO: Use Paragon HyperLink with Icon. */}
|
||||||
{/* Would need to add rel to paragon if we still need it. */}
|
{/* Would need to add rel to paragon if we still need it. */}
|
||||||
<li>
|
<li>
|
||||||
<a href={facebookUrl} title="Facebook" rel="noopener noreferrer" target="_blank">
|
<a
|
||||||
<Icon className={['fa', 'fa-facebook-square', 'fa-2x']} screenReaderText={`Like ${siteName} on Facebook`} />
|
href={facebookUrl}
|
||||||
|
title="Facebook"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
onClick={this.externalLinkClickHandler}
|
||||||
|
>
|
||||||
|
<Icon id="edx-footer-icon-facebook" className={['fa', 'fa-facebook-square', 'fa-2x']} screenReaderText={`Like ${siteName} on Facebook`} />
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href={twitterUrl}
|
||||||
|
title="Twitter"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
onClick={this.externalLinkClickHandler}
|
||||||
|
>
|
||||||
|
<Icon id="edx-footer-icon-twitter" className={['fa', 'fa-twitter-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on Twitter`} />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href={twitterUrl} title="Twitter" rel="noopener noreferrer" target="_blank">
|
<a
|
||||||
<Icon className={['fa', 'fa-twitter-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on Twitter`} />
|
href={youTubeUrl}
|
||||||
|
title="Youtube"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
onClick={this.externalLinkClickHandler}
|
||||||
|
>
|
||||||
|
<Icon id="edx-footer-icon-youtube" className={['fa', 'fa-youtube-square', 'fa-2x']} screenReaderText={`Subscribe to the ${siteName} YouTube channel`} />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href={youTubeUrl} title="Youtube" rel="noopener noreferrer" target="_blank">
|
<a
|
||||||
<Icon className={['fa', 'fa-youtube-square', 'fa-2x']} screenReaderText={`Subscribe to the ${siteName} YouTube channel`} />
|
href={linkedInUrl}
|
||||||
|
title="LinkedIn"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
onClick={this.externalLinkClickHandler}
|
||||||
|
>
|
||||||
|
<Icon id="edx-footer-icon-linkedin" className={['fa', 'fa-linkedin-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on LinkedIn`} />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href={linkedInUrl} title="LinkedIn" rel="noopener noreferrer" target="_blank">
|
<a
|
||||||
<Icon className={['fa', 'fa-linkedin-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on LinkedIn`} />
|
href={googlePlusUrl}
|
||||||
|
title="Google+"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
onClick={this.externalLinkClickHandler}
|
||||||
|
>
|
||||||
|
<Icon id="edx-footer-icon-google" className={['fa', 'fa-google-plus-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on Google+`} />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href={googlePlusUrl} title="Google+" rel="noopener noreferrer" target="_blank">
|
<a
|
||||||
<Icon className={['fa', 'fa-google-plus-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on Google+`} />
|
href={redditUrl}
|
||||||
</a>
|
title="Reddit"
|
||||||
</li>
|
rel="noopener noreferrer"
|
||||||
<li>
|
target="_blank"
|
||||||
<a href={redditUrl} title="Reddit" rel="noopener noreferrer" target="_blank">
|
onClick={this.externalLinkClickHandler}
|
||||||
|
>
|
||||||
<Icon className={['fa', 'fa-reddit-square', 'fa-2x']} screenReaderText={`Subscribe to the ${siteName} subreddit`} />
|
<Icon className={['fa', 'fa-reddit-square', 'fa-2x']} screenReaderText={`Subscribe to the ${siteName} subreddit`} />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -80,7 +137,7 @@ class SiteFooter extends React.Component {
|
|||||||
mobileLinks = (
|
mobileLinks = (
|
||||||
<ul className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5">
|
<ul className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5">
|
||||||
<li>
|
<li>
|
||||||
<a href={appleAppStoreUrl} rel="noopener noreferrer" target="_blank">
|
<a href={appleAppStoreUrl} rel="noopener noreferrer" target="_blank" onClick={this.externalLinkClickHandler}>
|
||||||
<img
|
<img
|
||||||
className="max-height-39"
|
className="max-height-39"
|
||||||
alt={`Download the ${siteName} mobile app from the Apple App Store`}
|
alt={`Download the ${siteName} mobile app from the Apple App Store`}
|
||||||
@@ -89,7 +146,7 @@ class SiteFooter extends React.Component {
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href={googlePlayUrl} rel="noopener noreferrer" target="_blank">
|
<a href={googlePlayUrl} rel="noopener noreferrer" target="_blank" onClick={this.externalLinkClickHandler}>
|
||||||
<img
|
<img
|
||||||
className="max-height-39"
|
className="max-height-39"
|
||||||
alt={`Download the ${siteName} mobile app from Google Play`}
|
alt={`Download the ${siteName} mobile app from Google Play`}
|
||||||
@@ -136,7 +193,7 @@ class SiteFooter extends React.Component {
|
|||||||
<div className="area-3">
|
<div className="area-3">
|
||||||
<h2>Legal</h2>
|
<h2>Legal</h2>
|
||||||
<ul className="list-unstyled p-0 m-0">
|
<ul className="list-unstyled p-0 m-0">
|
||||||
<li><a href={termsOfServiceUrl}>Terms of Service & Honor Code</a></li>
|
<li><a href={termsOfServiceUrl}>Terms of Service & Honor Code</a></li>
|
||||||
<li><a href={privacyPolicyUrl}>Privacy Policy</a></li>
|
<li><a href={privacyPolicyUrl}>Privacy Policy</a></li>
|
||||||
<li><a href={this.renderMarketingSiteUrl('/accessibility')}>Accessibility Policy</a></li>
|
<li><a href={this.renderMarketingSiteUrl('/accessibility')}>Accessibility Policy</a></li>
|
||||||
<li><a href={this.renderMarketingSiteUrl('/trademarks')}>Trademark Policy</a></li>
|
<li><a href={this.renderMarketingSiteUrl('/trademarks')}>Trademark Policy</a></li>
|
||||||
@@ -188,6 +245,7 @@ SiteFooter.propTypes = {
|
|||||||
showMobileLinks: PropTypes.bool,
|
showMobileLinks: PropTypes.bool,
|
||||||
appleAppStoreUrl: PropTypes.string,
|
appleAppStoreUrl: PropTypes.string,
|
||||||
googlePlayUrl: PropTypes.string,
|
googlePlayUrl: PropTypes.string,
|
||||||
|
handleAllTrackEvents: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
SiteFooter.defaultProps = {
|
SiteFooter.defaultProps = {
|
||||||
@@ -212,3 +270,4 @@ SiteFooter.defaultProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default SiteFooter;
|
export default SiteFooter;
|
||||||
|
export { EVENT_NAMES };
|
||||||
|
|||||||
Reference in New Issue
Block a user