Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a19c762cf7 | ||
|
|
045e28d0ef | ||
|
|
e39ac1ca43 | ||
|
|
2ed1a1aa8c |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
coverage
|
||||
dist
|
||||
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
|
||||
```
|
||||
43
README.rst
Normal file
43
README.rst
Normal file
@@ -0,0 +1,43 @@
|
||||
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.
|
||||
|
||||
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
|
||||
@@ -19,7 +19,8 @@
|
||||
"start": "NODE_ENV=development BABEL_ENV=development node_modules/.bin/webpack-dev-server --config=config/webpack.dev.config.js --progress",
|
||||
"test": "jest --coverage",
|
||||
"snapshot": "jest --updateSnapshot",
|
||||
"travis-deploy-once": "travis-deploy-once"
|
||||
"travis-deploy-once": "travis-deploy-once",
|
||||
"watch": "watch 'npm run build' ./src"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -68,6 +69,7 @@
|
||||
"source-map-loader": "^0.2.1",
|
||||
"style-loader": "^0.20.2",
|
||||
"travis-deploy-once": "^5.0.0",
|
||||
"watch": "^1.0.2",
|
||||
"webpack": "^4.19.1",
|
||||
"webpack-cli": "^3.1.0",
|
||||
"webpack-dev-server": "^3.1.9",
|
||||
|
||||
@@ -180,6 +180,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://www.facebook.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="Facebook"
|
||||
@@ -199,6 +200,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://www.twitter.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="Twitter"
|
||||
@@ -237,6 +239,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://www.linkedin.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="LinkedIn"
|
||||
@@ -256,6 +259,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://plus.google.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="Google+"
|
||||
@@ -275,6 +279,7 @@ exports[`<SiteFooter /> does not render mobile links 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://reddit.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="Reddit"
|
||||
@@ -486,6 +491,7 @@ exports[`<SiteFooter /> does not render social links 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://store.apple.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
@@ -499,6 +505,7 @@ exports[`<SiteFooter /> does not render social links 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://play.google.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
@@ -704,6 +711,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://www.facebook.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="Facebook"
|
||||
@@ -723,6 +731,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://www.twitter.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="Twitter"
|
||||
@@ -761,6 +770,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://www.linkedin.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="LinkedIn"
|
||||
@@ -780,6 +790,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://plus.google.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="Google+"
|
||||
@@ -799,6 +810,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://reddit.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="Reddit"
|
||||
@@ -822,6 +834,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://store.apple.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
@@ -835,6 +848,7 @@ exports[`<SiteFooter /> renders correctly 1`] = `
|
||||
<li>
|
||||
<a
|
||||
href="https://play.google.com"
|
||||
onClick={[Function]}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
|
||||
@@ -2,7 +2,26 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Hyperlink, Icon } from '@edx/paragon';
|
||||
|
||||
const EVENT_NAMES = {
|
||||
FOOTER_LINK: 'edx.bi.footer.link',
|
||||
};
|
||||
|
||||
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() {
|
||||
return (
|
||||
<img src={this.props.siteLogo} alt={`${this.props.siteName} logo`} />
|
||||
@@ -33,32 +52,69 @@ class SiteFooter extends React.Component {
|
||||
{/* TODO: Use Paragon HyperLink with Icon. */}
|
||||
{/* Would need to add rel to paragon if we still need it. */}
|
||||
<li>
|
||||
<a href={facebookUrl} title="Facebook" rel="noopener noreferrer" target="_blank">
|
||||
<a
|
||||
href={facebookUrl}
|
||||
title="Facebook"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
onClick={this.externalLinkClickHandler}
|
||||
>
|
||||
<Icon 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">
|
||||
<a
|
||||
href={twitterUrl}
|
||||
title="Twitter"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
onClick={this.externalLinkClickHandler}
|
||||
>
|
||||
<Icon className={['fa', 'fa-twitter-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on Twitter`} />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href={youTubeUrl} title="Youtube" rel="noopener noreferrer" target="_blank">
|
||||
<a
|
||||
href={youTubeUrl}
|
||||
title="Youtube"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon className={['fa', 'fa-youtube-square', 'fa-2x']} screenReaderText={`Subscribe to the ${siteName} YouTube channel`} />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href={linkedInUrl} title="LinkedIn" rel="noopener noreferrer" target="_blank">
|
||||
<a
|
||||
href={linkedInUrl}
|
||||
title="LinkedIn"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
onClick={this.externalLinkClickHandler}
|
||||
>
|
||||
<Icon className={['fa', 'fa-linkedin-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on LinkedIn`} />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href={googlePlusUrl} title="Google+" rel="noopener noreferrer" target="_blank">
|
||||
<a
|
||||
href={googlePlusUrl}
|
||||
title="Google+"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
onClick={this.externalLinkClickHandler}
|
||||
>
|
||||
<Icon className={['fa', 'fa-google-plus-square', 'fa-2x']} screenReaderText={`Follow ${siteName} on Google+`} />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href={redditUrl} title="Reddit" rel="noopener noreferrer" 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`} />
|
||||
</a>
|
||||
</li>
|
||||
@@ -80,7 +136,7 @@ class SiteFooter extends React.Component {
|
||||
mobileLinks = (
|
||||
<ul className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5">
|
||||
<li>
|
||||
<a href={appleAppStoreUrl} rel="noopener noreferrer" target="_blank">
|
||||
<a href={appleAppStoreUrl} rel="noopener noreferrer" target="_blank" onClick={this.externalLinkClickHandler}>
|
||||
<img
|
||||
className="max-height-39"
|
||||
alt={`Download the ${siteName} mobile app from the Apple App Store`}
|
||||
@@ -89,7 +145,7 @@ class SiteFooter extends React.Component {
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href={googlePlayUrl} rel="noopener noreferrer" target="_blank">
|
||||
<a href={googlePlayUrl} rel="noopener noreferrer" target="_blank" onClick={this.externalLinkClickHandler}>
|
||||
<img
|
||||
className="max-height-39"
|
||||
alt={`Download the ${siteName} mobile app from Google Play`}
|
||||
@@ -136,7 +192,7 @@ class SiteFooter extends React.Component {
|
||||
<div className="area-3">
|
||||
<h2>Legal</h2>
|
||||
<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={this.renderMarketingSiteUrl('/accessibility')}>Accessibility Policy</a></li>
|
||||
<li><a href={this.renderMarketingSiteUrl('/trademarks')}>Trademark Policy</a></li>
|
||||
@@ -188,6 +244,7 @@ SiteFooter.propTypes = {
|
||||
showMobileLinks: PropTypes.bool,
|
||||
appleAppStoreUrl: PropTypes.string,
|
||||
googlePlayUrl: PropTypes.string,
|
||||
handleAllTrackEvents: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
SiteFooter.defaultProps = {
|
||||
@@ -212,3 +269,4 @@ SiteFooter.defaultProps = {
|
||||
};
|
||||
|
||||
export default SiteFooter;
|
||||
export { EVENT_NAMES };
|
||||
|
||||
Reference in New Issue
Block a user