Compare commits

...

178 Commits

Author SHA1 Message Date
renovate[bot]
e6835f9c56 fix(deps): update font awesome to v6 (#258)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Muhammad Abdullah Waheed <42172960+abdullahwaheed@users.noreply.github.com>
Co-authored-by: Bilal Qamar <59555732+BilalQamar95@users.noreply.github.com>
2023-02-01 15:00:03 +05:00
renovate[bot]
a0c19faa92 chore(deps): update dependency redux to v4.2.1 2023-01-30 12:55:34 +00:00
Bilal Qamar
fa37ebb828 chore: update dependency @edx/frontend-build to v12.4.19 (#266) 2023-01-26 11:40:08 +05:00
Muhammad Abdullah Waheed
a24972b64f Revert "chore(deps): update dependency semantic-release to v20 (#263)" (#264)
This reverts commit abb22a82ba.
2023-01-20 12:26:36 +05:00
renovate[bot]
abb22a82ba chore(deps): update dependency semantic-release to v20 (#263)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-20 12:20:04 +05:00
dependabot[bot]
1df0b94a8c build(deps): bump json5 from 1.0.1 to 1.0.2 (#261)
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-18 18:38:59 +05:00
renovate[bot]
d563e2f444 chore(deps): update dependency @edx/brand to v1.2.0 2023-01-09 10:14:23 +00:00
renovate[bot]
92a210f81d chore(deps): update dependency @edx/frontend-build to v12.4.15 2022-12-22 01:03:46 +00:00
Bilal Qamar
1b92a3c505 feat: updated paragon to v20 (#254)
* feat: updated paragon to v20
2022-12-08 17:18:26 +05:00
edX requirements bot
f88d47275b fix: -t flag added in pull translation command (#256) 2022-11-30 16:47:10 +05:00
renovate[bot]
26f3900602 chore(deps): update dependency @edx/frontend-build to v12.4.0 2022-11-28 08:28:51 +00:00
Muhammad Abdullah Waheed
a9db712240 Merge pull request #253 from openedx/bilalqamar95/dependabot-issues-resolution
refactor: bumped minimatch, recursive-readdir & loader-utils
2022-11-23 14:31:26 +05:00
Bilal Qamar
739cce6c50 refactor: bumped minimatch, recursive-readdir & loader-utils 2022-11-22 15:51:17 +05:00
renovate[bot]
3a19e219bb chore(deps): update actions/setup-node action to v3 (#209)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-15 19:06:09 +05:00
julianajlk
12511689e8 fix: Change frontend-platform peer dependency to v2 or v3 range 2022-11-14 20:19:15 +00:00
renovate[bot]
f084393cc9 chore(deps): update dependency semantic-release to v19.0.5 2022-11-14 07:58:10 +00:00
renovate[bot]
4035ff122c chore(deps): update dependency react-router-dom to v5.3.4 2022-11-14 07:52:15 +00:00
Leangseu Kim
159b5a842e feat: upgrade frontend platform to version 3 2022-11-10 11:08:04 +00:00
renovate[bot]
b06c8b5d01 chore(deps): update dependency react-redux to v7.2.9 2022-11-07 11:10:32 +00:00
renovate[bot]
c79da49208 chore(deps): update dependency enzyme-adapter-react-16 to v1.15.7 2022-11-07 08:43:12 +00:00
Leangseu Kim
82b3310a8f fix: downgrade frontend-platform 2022-11-01 16:09:19 -04:00
Abdullah Waheed
fcd641259b refactor: updated renovate config to auto update minor and patch versions of edx dependencies 2022-10-27 09:26:18 -03:00
Abdullah Waheed
509276df12 feat: added new translations in Makefile and updated all the translations 2022-10-27 09:25:07 -03:00
Bilal Qamar
4527baef5a refactor: upgraded frontend-build to v12 & resolved eslint issues 2022-10-26 10:35:10 -03:00
Muhammad Abdullah Waheed
8183143ae5 Merge pull request #225 from openedx/dependabot/npm_and_yarn/terser-4.8.1
build(deps): bump terser from 4.8.0 to 4.8.1
2022-10-25 16:07:08 +05:00
dependabot[bot]
91311f25da build(deps-dev): bump semantic-release from 17.4.7 to 19.0.3 (#217)
Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 17.4.7 to 19.0.3.
- [Release notes](https://github.com/semantic-release/semantic-release/releases)
- [Commits](https://github.com/semantic-release/semantic-release/compare/v17.4.7...v19.0.3)

---
updated-dependencies:
- dependency-name: semantic-release
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-25 16:06:26 +05:00
renovate[bot]
ccef5de855 chore(deps): update actions/checkout action to v3 (#205)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-25 15:39:10 +05:00
Muhammad Abdullah Waheed
01fa97055f Merge pull request #199 from openedx/dependabot/npm_and_yarn/async-2.6.4
build(deps): bump async from 2.6.3 to 2.6.4
2022-10-25 15:38:22 +05:00
Muhammad Abdullah Waheed
3cff0970a3 Merge pull request #191 from openedx/dependabot/npm_and_yarn/node-forge-1.3.0
build(deps): bump node-forge from 1.2.1 to 1.3.0
2022-10-25 15:37:26 +05:00
renovate[bot]
f2c879999d chore(deps): update dependency marked to 4.0.10 [security] (#186)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-25 15:36:30 +05:00
Ben Warzeski
3f18cf7c9d Merge pull request #236 from muselesscreator/platform_3.0
fix: frontend platform peer dependency to 3.x
2022-09-27 10:01:59 -04:00
Ben Warzeski
30796204b8 fix: frontend platform peer dependency to 3.x 2022-09-27 09:27:07 -04:00
dependabot[bot]
d206ecf3ad build(deps): bump async from 2.6.3 to 2.6.4
Bumps [async](https://github.com/caolan/async) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.3...v2.6.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-26 18:32:49 +00:00
Ben Warzeski
f3094e1725 Merge pull request #234 from muselesscreator/platform_3.0
feat: update frontend-platform to v3.0.1
2022-09-26 14:31:09 -04:00
Ben Warzeski
5bbd266834 feat: update frontend-platform to v3.0.1 2022-09-26 14:20:26 -04:00
Sarina Canelake
37eed0578f Merge pull request #233 from openedx/tcril/fix-gh-org-url
Fix github url strings (org edx -> openedx)
2022-09-14 09:44:26 -04:00
Sarina Canelake
acbe489a7c fix: update path to .github workflows to read from openedx org 2022-09-10 18:03:48 -04:00
Sarina Canelake
2cfbb40265 fix: fix github url strings (org edx -> openedx) 2022-09-07 08:52:02 -04:00
Muhammad Abdullah Waheed
3e1264b710 Merge pull request #229 from openedx/abdullahwaheed/run-build-in-ci
Npm run build script in Github CI
2022-08-16 11:17:52 +05:00
Abdullah Waheed
bf60da6554 feat: added build script in github CI 2022-08-12 19:12:07 +05:00
renovate[bot]
cf879e53be fix(deps): update dependency @fortawesome/react-fontawesome to v0.2.0 2022-07-25 12:09:39 +00:00
dependabot[bot]
e0a634900d build(deps): bump terser from 4.8.0 to 4.8.1
Bumps [terser](https://github.com/terser/terser) from 4.8.0 to 4.8.1.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/commits)

---
updated-dependencies:
- dependency-name: terser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-20 21:53:15 +00:00
renovate[bot]
15ae025990 chore(deps): update dependency @edx/frontend-platform to v2.5.0 2022-07-18 10:39:03 +00:00
renovate[bot]
efd85745fd chore(deps): update dependency @edx/paragon to v19.25.3 2022-06-20 13:07:57 +00:00
Maman Khan
fc5df4af36 fix: removed depreciated package codecov (#220) 2022-06-20 08:06:00 +05:00
Adolfo R. Brandes
f657c719ec Merge pull request #219 from muselesscreator/platform_version_bump
feat: bump frontend-platform to 2.3.0
2022-06-15 22:22:32 +01:00
Ben Warzeski
6c346c18f9 feat: bump frontend-platform to 2.3.0 2022-06-14 15:56:58 -04:00
Renovate Bot
2b9c5affbc chore(deps): update dependency @edx/paragon to v19.25.1 2022-06-06 11:56:43 +00:00
Renovate Bot
4a13120d24 chore(deps): update dependency @edx/paragon to v19.25.0 2022-05-30 12:25:15 +00:00
Renovate Bot
8e0587f871 chore(deps): update dependency react-router-dom to v5.3.3 2022-05-23 12:26:35 +00:00
Renovate Bot
7cc2f74562 chore(deps): pin dependency semantic-release to v 2022-05-23 12:19:25 +00:00
Renovate Bot
3b13fc29b4 chore(deps): update dependency @edx/frontend-platform to v1.15.6 2022-05-16 20:54:51 +00:00
edX requirements bot
3f12c52221 chore!: Dropped support for Node 12 (#207)
BREAKING CHANGE: Dropped Node12 support
2022-05-16 20:56:26 +05:00
Renovate Bot
826d071566 chore(deps): update dependency @edx/paragon to v19.22.1 2022-05-16 11:37:34 +00:00
edX requirements bot
b66ae651b6 feat: Add package-lock file version check (#206) 2022-05-12 12:22:31 +05:00
Renovate Bot
d23a4e2443 chore(deps): update dependency redux to v4.2.0 2022-05-09 10:46:31 +00:00
Renovate Bot
898b90eb07 chore(deps): update dependency @edx/paragon to v19.20.0 2022-05-02 11:29:16 +00:00
Renovate Bot
dbb806d0a3 chore(deps): update dependency @edx/frontend-build to v9.2.2 2022-05-02 11:21:30 +00:00
Renovate Bot
702bce8587 chore(deps): update dependency prop-types to v15.8.1 2022-04-25 11:43:11 +00:00
Renovate Bot
0bd6c9d452 chore(deps): update dependency @edx/paragon to v19.19.0 2022-04-25 11:35:17 +00:00
Renovate Bot
3d4d356665 chore(deps): update dependency @edx/paragon to v19.18.0 2022-04-18 14:59:37 +00:00
Renovate Bot
e656865502 chore(deps): update dependency react-router-dom to v5.3.1 2022-04-18 14:51:49 +00:00
Renovate Bot
2b4283ac5f chore(deps): update dependency @edx/paragon to v19.15.0 2022-04-11 12:59:17 +00:00
Renovate Bot
38d9a2076b fix(deps): update dependency @fortawesome/react-fontawesome to v0.1.18 2022-04-11 12:51:38 +00:00
Usama Sadiq
a31d1a5387 Merge pull request #190 from openedx/jenkins/transifex-client-migration-dcc3617
fix: transifex migration to new client
2022-04-06 12:43:06 +05:00
UsamaSadiq
a374cee7dd build: update transifex pull translations command 2022-04-05 15:35:38 +05:00
Renovate Bot
3f50a4d333 chore(deps): update dependency react-redux to v7.2.8 2022-04-04 11:11:31 +00:00
Renovate Bot
45f0f20f0f chore(deps): update dependency @edx/frontend-build to v9.1.4 2022-04-04 11:03:03 +00:00
dependabot[bot]
fb06f7d9f9 build(deps): bump node-forge from 1.2.1 to 1.3.0
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.2.1 to 1.3.0.
- [Release notes](https://github.com/digitalbazaar/forge/releases)
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.2.1...v1.3.0)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-26 06:39:29 +00:00
Adolfo R. Brandes
29a5db5e1a Merge pull request #178 from ayrtonlr/master
Change the logo to link to the LMS
2022-03-24 06:46:46 -03:00
Ayrton Lima
7982251640 fix: change logo anchor tag to link to the LMS 2022-03-23 20:21:53 -03:00
edX requirements bot
9824aecd16 fix: transifex migration to new client 2022-03-17 08:47:05 -04:00
Renovate Bot
dcc361747e chore(deps): update dependency @edx/frontend-build to v9.1.2 2022-03-14 10:12:05 +00:00
Jawayria
863ecb41bd Merge pull request #187 from openedx/jawayria/upgrade-deps
fix: Upgraded dependencies for Node 16 support
2022-03-04 14:47:23 +05:00
Jawayria
f6d02d177d fix: Upgraded dependencies for Node 16 support 2022-03-04 13:53:46 +05:00
David Joy
7e196f48cf build: We no longer want this CODEOWNERS file.
The community-engineering team no longer exists.
2022-02-28 09:53:13 -05:00
Jawayria
46e4c78af8 Merge pull request #185 from openedx/jawayria/fix-release-ci
fix: Added semantic-release v17 in package.json to fix release CI
2022-02-28 18:44:58 +05:00
Jawayria
affbcbeb19 fix: Added semantic-release v17 in package.json to fix release CI 2022-02-28 17:31:34 +05:00
Jawayria
8c10919eb9 Merge pull request #177 from openedx/jenkins/node-16-2b56d27
feat: Added support for node v16
2022-02-25 17:25:02 +05:00
edX requirements bot
314781ac0b feat: Added support for Node v16 2022-02-25 17:22:36 +05:00
Sarina Canelake
b75ab299bd Merge DEPR automation workflow
Add DEPR workflow automation
2022-02-24 15:21:45 -05:00
Sarina Canelake
1fb4475b9a build: add DEPR workflow automation 2022-02-23 14:36:53 -05:00
Renovate Bot
2b56d270a2 chore(deps): update dependency @edx/frontend-platform to v1.14.1 2021-11-29 09:47:56 +00:00
Renovate Bot
395c9240a0 chore(deps): update dependency @edx/frontend-platform to v1.14.0 2021-11-08 09:03:26 +00:00
Renovate Bot
60ceedced9 chore(deps): update dependency redux to v4.1.2 2021-11-01 09:59:30 +00:00
Renovate Bot
032e4dd73f chore(deps): update dependency react-redux to v7.2.6 2021-11-01 09:48:29 +00:00
Renovate Bot
212bc015ad fix(deps): update dependency @fortawesome/react-fontawesome to v0.1.16 2021-10-25 09:42:17 +00:00
Renovate Bot
d72eaa6fab chore(deps): update dependency husky to v7.0.4 2021-10-25 09:30:59 +00:00
Ned Batchelder
1f5b74de21 build: no need for local commitlint.config.js 2021-10-22 14:23:04 -04:00
Ned Batchelder
07728e1498 build: use the organization commitlint check 2021-10-07 13:48:27 -04:00
Renovate Bot
5d44307136 chore(deps): update commitlint monorepo to v13.2.0 2021-10-04 08:21:39 +00:00
Renovate Bot
1769069cfe chore(deps): update dependency @edx/frontend-platform to v1.12.7 2021-09-20 08:33:36 +00:00
Renovate Bot
2fb0cac399 chore(deps): update dependency @edx/frontend-platform to v1.12.6 2021-09-13 11:48:51 +00:00
Renovate Bot
807dc66714 chore(deps): update dependency react-router-dom to v5.3.0 2021-09-06 08:38:27 +00:00
Renovate Bot
ea837695e9 chore(deps): update dependency react-redux to v7.2.5 2021-09-06 08:26:11 +00:00
stvn
e4801b8b81 merge(#135): renovate/codecov-codecov-action-2.x
commits
=======
- chore(deps): update codecov/codecov-action action to v2
2021-09-01 15:35:58 -07:00
Renovate Bot
89337c4819 chore(deps): update codecov/codecov-action action to v2 2021-08-30 08:41:29 +00:00
Renovate Bot
c75f6c079e chore(deps): update dependency husky to v7.0.2 2021-08-30 08:41:09 +00:00
Renovate Bot
77c251467c chore(deps): update dependency @edx/frontend-platform to v1.12.4 2021-08-23 09:20:49 +00:00
Renovate Bot
caba23d51b chore(deps): update dependency @edx/frontend-platform to v1.12.3 2021-08-16 06:55:48 +00:00
stvn
efbae26c56 merge(#137): renovate/major-commitlint-monorepo
commits
=======
- chore(deps): update commitlint monorepo to v13
2021-08-10 10:34:25 -07:00
Renovate Bot
efeacb8b73 chore(deps): update commitlint monorepo to v13 2021-08-10 06:39:06 +00:00
stvn
a0865c9c56 merge(#131): renovate/husky-7.x
commits
=======
- chore(deps): update dependency husky to v7
2021-08-09 23:34:47 -07:00
Renovate Bot
7cfd6932d5 chore(deps): update dependency husky to v7 2021-08-09 08:59:46 +00:00
Renovate Bot
e2f92992b6 fix(deps): update font awesome 2021-08-09 08:49:15 +00:00
Renovate Bot
f37e6c164e chore(deps): update dependency redux to v4.1.1 2021-08-09 08:35:40 +00:00
Renovate Bot
fef30fb8b5 chore(deps): update dependency @edx/frontend-platform to v1.11.3 2021-08-02 06:43:59 +00:00
Renovate Bot
bcac04d0cc chore(deps): update dependency codecov to v3.8.3 2021-07-26 07:06:11 +00:00
Renovate Bot
15ff0203ab chore(deps): update dependency @edx/frontend-platform to v1.11.1 2021-07-12 08:08:45 +00:00
stvn
940294d2a0 merge(#93): renovate/major-commitlint-monorepo
commits
=======
- chore(deps): update commitlint monorepo to v12
2021-06-14 15:35:19 -07:00
Renovate Bot
acd4a843a4 chore(deps): update commitlint monorepo to v12 2021-06-14 20:17:17 +00:00
Renovate Bot
d8ee5425bf chore(deps): update dependency @edx/paragon to v12.8.0 2021-06-14 20:13:11 +00:00
Renovate Bot
1d9e8d3c47 chore(deps): update dependency @edx/frontend-platform to v1.11.0 2021-06-14 20:04:09 +00:00
stvn
4d370f8a75 merge(#117): renovate/husky-6.x
commits
=======
- chore(deps): update dependency husky to v6
2021-06-11 23:22:51 -07:00
Renovate Bot
2a2be8eddb chore(deps): update dependency husky to v6 2021-06-11 20:56:20 +00:00
Renovate Bot
e7624adbfb chore(deps): update dependency @edx/frontend-build to v5.6.14 2021-06-11 20:45:14 +00:00
Renovate Bot
5d0a418e85 chore(deps): update dependency redux to v4.1.0 2021-06-09 07:17:17 +00:00
stvn
f5b18cdd54 merge(#111): renovate/actions-setup-node-2.x
commits
=======
- chore(deps): update actions/setup-node action to v2
2021-06-08 10:26:22 -07:00
Renovate Bot
d5d290bcbe chore(deps): update actions/setup-node action to v2 2021-06-08 08:45:20 +00:00
Renovate Bot
49c02c157b chore(deps): update react monorepo to v16.14.0 2021-06-08 08:35:06 +00:00
Renovate Bot
94b4aa7402 chore(deps): update dependency react-redux to v7.2.4 2021-06-08 08:16:27 +00:00
stvn
a9fe23287f merge(#19): build/renovate
commits
=======
- build(renovate): fix json syntax
2021-06-07 22:38:00 -07:00
stvn
30874b4972 build(renovate): fix json syntax 2021-06-07 22:37:21 -07:00
stvn
14d53ef514 merge(#125): build/renovate-stricter
commits
=======
- build(renovate): be more selective about automerging devDependencies
2021-06-04 13:41:14 -07:00
stvn
5c9270d88a build(renovate): be more selective about automerging devDependencies 2021-06-04 13:22:06 -07:00
Renovate Bot
f70ca27b34 chore(deps): update dependency react-router-dom to v5.2.0 2021-06-04 01:53:30 +00:00
Renovate Bot
d247e88541 fix(deps): update font awesome 2021-06-04 01:32:35 +00:00
Renovate Bot
ea257afcca chore(deps): update dependency husky to v3.1.0 2021-06-03 22:39:52 +00:00
Renovate Bot
24603cf98f chore(deps): update dependency enzyme-adapter-react-16 to v1.15.6 2021-06-03 22:14:10 +00:00
Renovate Bot
4249bbc6df chore(deps): update dependency enzyme to v3.11.0 2021-06-03 21:47:26 +00:00
Renovate Bot
611beb8294 chore(deps): pin dependencies 2021-06-03 21:20:20 +00:00
Renovate Bot
87803604b1 chore(deps): update dependency codecov to v3.8.2 2021-06-03 20:52:09 +00:00
Renovate Bot
99344d93a4 chore(deps): update commitlint monorepo 2021-06-03 20:21:45 +00:00
stvn
2a718743ea merge(#124): build/renovate
commits
=======
- build(renovate): be more liberal about what automerges
2021-06-03 11:15:55 -07:00
stvn
4fe8909ad5 build(renovate): be more liberal about what automerges
based on https://github.com/edx/frontend-app-account .
2021-06-03 10:48:02 -07:00
stvn
a0dc37dfb5 merge: stvn/own/code 2021-05-26 13:42:27 -07:00
stvn
e4917030fa build: add CODEOWNERS; edx/community-engineering
Background
==========
As part of our Squad-based ownership, we should stay on top of what
happens in these repositories. However, due to the number of
repositories (and subsequently pull requests) across the edX ecosystem,
it is challenging to stay on top of notifications, separating the
'signal' from the 'noise'. Email filters can go a long way to taming
Inbox notifications, but this is manual and requires maintenance as
Squad ownership changes. It also fails to account for Github-specific behavior.

Proposal
========
By leveraging Github support for `CODEOWNERS` files [1],
we can ensure that our team is at least CCed explicitly, here,
in the form a requested review. This request is just that, a request,
not a requirement; we are not enacting any new merge requirements
at this time.

- [1] https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
2021-05-26 12:15:49 -07:00
David Joy
c756f42c28 docs: Updating README with repository details. (#122)
* docs: Specify component usage requirements in the README.

This includes both the component's dependency on @edx/frontend-platform, as well as its required environment variables.

* docs: fix verbatim formatting

* docs: improving footer README

Including headings and formatting consistent with frontend-component-header.  Hopefully others soon.
2021-05-14 12:57:09 -04:00
Renovate Bot
1b6a5eda0b chore(deps): update dependency @edx/frontend-platform to v1.8.4 2021-02-07 11:57:37 +00:00
David Joy
cbaf4bbb9e fix: remove unnecessary paragon peer dependency (#114)
The actual component code doesn’t use paragon.  Only the example app does, meaning this isn’t really a peer dependency.
2021-02-04 14:25:31 -05:00
Renovate Bot
c990cbbf5e fix(deps): update font awesome 2021-01-31 09:56:38 +00:00
Renovate Bot
b41af87b8e chore(deps): update dependency @edx/frontend-platform to v1.8.1 2021-01-23 11:58:46 +00:00
Carla Duarte
a7d59a874c Merge pull request #108 from edx/ciduarte/AA-465
fix: remove unnecessary aria-label
2021-01-07 09:33:22 -05:00
Carla Duarte
d66d3b7b62 fix: remove unnecessary aria-label 2021-01-06 17:23:50 -05:00
Jawayria
7095e79471 Merge pull request #103 from Jawayria/update-badge
Updated the build status badge to point to travis-ci.com
2020-12-17 13:47:00 +05:00
Renovate Bot
4a9b3f2bfb fix(deps): update font awesome 2020-12-11 09:58:08 +00:00
Jeff Chaves
e4d23d366b feat: upgrading deps, retheme with from @edx/brand, pull logo from config settings (#104)
* feat: upgrading deps, use logo from @edx/brand

* feat: upgrading peer deps

* feat: pr feedback

* update snapshots and example app

* pull config from AppContext

Co-authored-by: Adam Stankiewicz <agstanki@gmail.com>
2020-11-30 14:00:26 -05:00
Adam Stankiewicz
2e75cc95cb ci: migrate to use GH actions (#106)
* ci: migrate to use GH actions

* ci: change gh action names
2020-11-30 13:56:29 -05:00
Jawayria
f64faf9f14 Updated the build status badge to point to travis-ci.com 2020-11-20 15:01:06 +05:00
Renovate Bot
0be3098191 chore(deps): update dependency codecov to v3.7.2 2020-07-22 03:36:15 +00:00
renovate[bot]
799cdb3b3c chore(deps): update dependency codecov to v3.7.1 [security] (#95)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2020-07-21 09:26:50 -04:00
Renovate Bot
370ae52c04 fix(deps): update dependency @fortawesome/fontawesome-svg-core to v1.2.30 2020-07-15 18:20:09 +00:00
Renovate Bot
5037a5610b fix(deps): update font awesome 2020-07-04 09:56:32 +00:00
Renovate Bot
0a91f8242f fix(deps): update dependency @fortawesome/fontawesome-svg-core to v1.2.28 2020-03-23 16:19:06 +00:00
Renovate Bot
457bd843cf fix(deps): update dependency @fortawesome/react-fontawesome to v0.1.9 2020-03-05 18:10:56 +00:00
Renovate Bot
777c697c41 fix(deps): update dependency @fortawesome/fontawesome-svg-core to v1.2.27 2020-02-07 16:09:34 +00:00
Renovate Bot
b3b32613c9 chore(deps): update dependency codecov to v3.6.5 2020-02-07 15:11:57 +00:00
Renovate Bot
a6f70e895a chore(deps): update dependency codecov to v3.6.4 2020-02-01 03:12:36 +00:00
Renovate Bot
1112b426f0 chore(deps): update dependency codecov to v3.6.3 2020-01-31 14:13:51 +00:00
Renovate Bot
17278cc355 chore(deps): update dependency codecov to v3.6.2 2020-01-23 20:22:47 +00:00
Renovate Bot
65c25bfc95 fix(deps): update dependency @fortawesome/fontawesome-svg-core to v1.2.26 2019-12-11 00:12:05 +00:00
Renovate Bot
75e8962563 fix(deps): update dependency @fortawesome/react-fontawesome to v0.1.8 2019-12-06 17:14:43 +00:00
Renovate Bot
65aba84491 fix(deps): update font awesome 2019-12-04 23:19:08 +00:00
Renovate Bot
093dfa6ac2 chore(deps): update react monorepo to v16.10.2 2019-12-04 22:15:57 +00:00
Renovate Bot
4637834750 chore(deps): update dependency husky to v3.0.9 2019-12-04 21:04:01 +00:00
Renovate Bot
a021e72359 chore(deps): update dependency @edx/paragon to v7.1.5 2019-12-04 20:39:24 +00:00
Renovate Bot
925ddb7adf chore(deps): update dependency @edx/frontend-platform to v1.1.6 2019-12-04 20:21:15 +00:00
David Joy
9ebcd15623 Update renovate.json 2019-12-04 14:25:58 -05:00
Adam Butterworth
3a2e553feb fix: upgrade frontend-build for i18n extract fix (#67) 2019-12-03 16:00:43 -05:00
Adam Butterworth
eb6c253e35 fix: upgrade frontend-build to fix translation job (#65) 2019-12-03 14:13:11 -05:00
David Joy
d2315c2c21 build: dev tweaks (#64)
* build: dev tweaks

need an eslintrc file and to gitignore .vscode directories

* Update .eslintrc.js
2019-12-03 10:46:32 -05:00
Adam Butterworth
f33a972933 fix: upgrade frontend-platform (#63) 2019-12-03 10:33:28 -05:00
Adam Butterworth
d540aaa390 feat: upgrade to frontend-platform (#60)
BREAKING CHANGE: This package now relies upon frontend-platform instead of individual runway packages.
2019-11-21 17:18:26 -05:00
Adam Butterworth
c64496dd08 Update README.rst 2019-10-08 12:54:29 -04:00
edX Transifex Bot
e94cf3ac2d fix(i18n): update translations 2019-10-06 16:33:20 -04:00
David Joy
d4259ef1f6 feat: handleAllTrackEvents is no longer used (#48)
* feat: use frontend-analytics directly

BREAKING CHANGE: handleAllTrackEvents is no longer part of the Footer props API.  The footer uses frontend-analytics’s sendTrackEvent directly.

Also updating other dependencies to keep them up to date.  This part should probably be a separate PR, technically.

* fix: remove unused dependency of frontend-logging

* fix: a little PR cleanup

* fix: putting frontend logging back

It’s needed by frontend-i18n and fails if it’s not there for tests.

* fix: pinning npm at 6
2019-10-02 14:59:12 -04:00
renovate[bot]
b4f35d37c8 chore(deps): add renovate.json (#47) 2019-10-02 12:34:44 -04:00
Adam Butterworth
83bad3d47b feat: repurpose as open edx footer (#46)
* feat: simplify prop api and bake in many values

* feat: refactor build and dev server

BREAKING CHANGE: The footer is now  transpiled from es6 preserving modules. To use this package in a project it must now be transpiled by the requiring project via webpack or other configuration

* feat: make this the open edx footer

BREAKING CHANGE: This footer now serves as the Open edX footer. For the edX footer see edx/frontend-component-footer-edx on github
2019-09-30 14:33:06 -04:00
55 changed files with 39258 additions and 25614 deletions

View File

@@ -1,28 +0,0 @@
{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions", "ie 11"]
}
}],
"babel-preset-react"
],
"plugins": [
"transform-object-rest-spread"
],
"env": {
"test": {
"plugins": [
"rewire"
]
},
"i18n": {
"plugins": [
["react-intl", {
"messagesDir": "./temp/babel-plugin-react-intl",
"moduleSourceName": "@edx/frontend-i18n"
}]
]
}
}
}

19
.env.development Normal file
View File

@@ -0,0 +1,19 @@
ACCESS_TOKEN_COOKIE_NAME=edx-jwt-cookie-header-payload
BASE_URL=localhost:8080
CREDENTIALS_BASE_URL=http://localhost:18150
CSRF_TOKEN_API_PATH=/csrf/api/v1/token
ECOMMERCE_BASE_URL=http://localhost:18130
LANGUAGE_PREFERENCE_COOKIE_NAME=openedx-language-preference
LMS_BASE_URL=http://localhost:18000
LOGIN_URL=http://localhost:18000/login
LOGOUT_URL=http://localhost:18000/login
MARKETING_SITE_BASE_URL=http://localhost:18000
ORDER_HISTORY_URL=localhost:1996/orders
REFRESH_ACCESS_TOKEN_ENDPOINT=http://localhost:18000/login_refresh
SEGMENT_KEY=null
SITE_NAME=Open edX
USER_INFO_COOKIE_NAME=edx-user-info
LOGO_URL=https://edx-cdn.org/v3/default/logo.svg
LOGO_TRADEMARK_URL=https://edx-cdn.org/v3/default/logo-trademark.svg
LOGO_WHITE_URL=https://edx-cdn.org/v3/default/logo-white.svg
FAVICON_URL=https://edx-cdn.org/v3/default/favicon.ico

View File

@@ -1,3 +1,4 @@
coverage
dist
example
node_modules

4
.eslintrc.js Normal file
View File

@@ -0,0 +1,4 @@
// eslint-disable-next-line import/no-extraneous-dependencies
const { createConfig } = require('@edx/frontend-build');
module.exports = createConfig('eslint');

View File

@@ -1,19 +0,0 @@
{
"extends": "eslint-config-edx",
"rules": {
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": [
"webpack.config.js",
"src/tests/setupTest.js",
"**/*.test.jsx",
"**/*.test.js"
]
}
]
},
"env": {
"jest": true
}
}

View File

@@ -0,0 +1,19 @@
# Run the workflow that adds new tickets that are either:
# - labelled "DEPR"
# - title starts with "[DEPR]"
# - body starts with "Proposal Date" (this is the first template field)
# to the org-wide DEPR project board
name: Add newly created DEPR issues to the DEPR project board
on:
issues:
types: [opened]
jobs:
routeissue:
uses: openedx/.github/.github/workflows/add-depr-ticket-to-depr-board.yml@master
secrets:
GITHUB_APP_ID: ${{ secrets.GRAPHQL_AUTH_APP_ID }}
GITHUB_APP_PRIVATE_KEY: ${{ secrets.GRAPHQL_AUTH_APP_PEM }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_ISSUE_BOT_TOKEN }}

37
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Default CI
on:
push:
branches:
- master
pull_request:
branches:
- '**'
jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
node: [16]
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Nodejs
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- name: Install dependencies
run: npm ci
- name: Validate package-lock.json changes
run: make validate-no-uncommitted-package-lock-changes
- name: Lint
run: npm run lint
- name: Test
run: npm run test
- name: Build
run: npm run build
- name: i18n_extract
run: npm run i18n_extract
- name: Coverage
uses: codecov/codecov-action@v3

10
.github/workflows/commitlint.yml vendored Normal file
View File

@@ -0,0 +1,10 @@
# Run commitlint on the commit messages in a pull request.
name: Lint Commit Messages
on:
- pull_request
jobs:
commitlint:
uses: openedx/.github/.github/workflows/commitlint.yml@master

View File

@@ -0,0 +1,13 @@
#check package-lock file version
name: Lockfile Version check
on:
push:
branches:
- master
pull_request:
jobs:
version-check:
uses: openedx/.github/.github/workflows/lockfileversion-check.yml@master

37
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Release CI
on:
push:
branches:
- master
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Validate package-lock.json changes
run: make validate-no-uncommitted-package-lock-changes
- name: Lint
run: npm run lint
- name: Test
run: npm run test
- name: i18n_extract
run: npm run i18n_extract
- name: Coverage
uses: codecov/codecov-action@v3
- name: Build
run: npm run build
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_NPM_TOKEN }}
run: npx semantic-release

3
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.DS_Store
coverage
dist
node_modules
@@ -7,3 +8,5 @@ temp
src/i18n/transifex_input.json
temp/babel-plugin-react-intl
/.vscode
module.config.js

View File

@@ -1,21 +0,0 @@
language: node_js
node_js:
- 8
cache:
directories:
- "~/.npm"
install:
- npm install
script:
- npm run lint
- npm run i18n_extract
- npm run test
- npm run build
- npm run is-es5
after_success:
- npm run travis-deploy-once "npm run semantic-release"
- npm run coveralls
env:
global:
- secure: dxQadqP6tsoJzHcqs/Hs5AjE42z45q8ZeWKP5HcjbXoJURB4gc1uIxLky0FA6ZpulaTgRVTLcWQbx9yOODc9PQuFnFEDWlCg5EP8tONzeu7BVlJvV5eakgGUhl9w2pekBKsTGhK5dDg2y2D8bGfIL55UX81uiWeytp8s/y8QNs/FNXx9ScJnfhnC+2RfW52fB7iW12F1VYdQfVe43o5PsHze+YhB3FU/ztGe3iMaQiq9QplZWpvqQMpI7pTjyUAX8ITiiPS6UvLFObgpXpfjZdgd+yveFoi3z8o8F0NkmzBphFeSYFjFZE0qJ8bnGNIZldanMeuUgHmDeTwVmKQFhH2LqqnfcdGgW6UsKcHkSN1G51zzad2dEwAHrgxj1NkMp3JfEed2C7Kvntl6KRjVDmYZqHJvt+e+AHNbpjzblOW8tYMIrdz0TeJdk4D9pP3B3tRCtP6fvQ3GLzAMnaCrSsN6hZ9YVxWku8sg8WNEDHl14sZsdgk312MlHIdiUw97FHGrqx/NCix4IkUlCBDbKYbKzbZp20FfzZcwNRNH74+k6xpOnMGSfq8gByEhm9y02MBL76HiAI2VGct2La1ExaUfoikYGoNaZpFcZyOZKo6PYTYHpiUJmqrEnDyVQEOOXUaVsxWXwnYq/mU4nOEPKCRbNpPoksZdNxf6jlmMi8s=
- secure: lrlV0WQaXTRJ2lqDkFZ+1RkRb7YM/STOViOHUNboXb5+1ReVwY0wklFDVk/Qigp3jkbqWfzkBmEjSDVGDLD61QjpGY4BsxZ/Jn3+KUdo0n82Ym6cI/je1fH2gqDLi4U8bylmnkI5oEjV/1txDxkj4hF5w/Leo/oGue3xQohpi//ihhm/PxzExj+QiDqyZPZ5RQZeqLfPEU3Wff04vLE5bRmy1nDTZrgm5Wb1n5ItGsyrUyrCGuAM9kIEun65Snb8hxCuU9pSm1w/xF73iOGLiiC8KZhLu6SxSKoC872ai1GpUXNIqA8kpVeH0Erf5opMtqJT3jTTan/VOFQEoOeAKhR0ga+5rfK2jkhhN77B98dGVndNCfBpDlgQxVv42H6riFk3payZT262QiUqDejiBDtSPTokTGxf7xFtQkQQahhxVXzC2HRKEkDTXNSP8cvk2JJ4zCcUgxJpycudLMuC/Xv0upK+Q0caItBrHxfVNnRKkjKqlDxRhA8nXTY8d2n19FNi7wahCECbyweJJ76EaJaa/Ib6remUBrbGLoQ2PkaSMBHAcn3+7+H/6x11b2s1RHj5qyfIyrvZcDDyNuxdXwpOkhtrkwZsjgtOfXL6IuxW5FExgPPr8B9nNwJJKdTxyxgfqtwBR5+m9nrMixzT6AMe95torZ6eX40gKZ/O9EU=

View File

@@ -1,8 +1,9 @@
[main]
host = https://www.transifex.com
[edx-platform.frontend-component-footer]
[o:open-edx:p:edx-platform:r:frontend-component-footer]
file_filter = src/i18n/messages/<lang>.json
source_file = src/i18n/transifex_input.json
source_lang = en
type = KEYVALUEJSON
type = KEYVALUEJSON

12
Makefile Executable file → Normal file
View File

@@ -1,5 +1,5 @@
transifex_resource = frontend-component-footer
transifex_langs = "ar,fr,es_419,zh_CN"
transifex_langs = "ar,fr,es_419,zh_CN,pt,it,de,uk,ru,hi,fr_CA"
transifex_utils = ./node_modules/.bin/transifex-utils.js
i18n = ./src/i18n
@@ -10,6 +10,14 @@ tx_url2 = https://www.transifex.com/api/2/project/edx-platform/resource/$(transi
# This directory must match .babelrc .
transifex_temp = ./temp/babel-plugin-react-intl
build:
rm -rf ./dist
./node_modules/.bin/fedx-scripts babel src --out-dir dist --source-maps --ignore **/*.test.jsx,**/__mocks__,**/__snapshots__,**/setupTest.js --copy-files
@# --copy-files will bring in everything else that wasn't processed by babel. Remove what we don't want.
@rm -rf dist/**/*.test.jsx
@rm -rf dist/**/__snapshots__
@rm -rf dist/__mocks__
requirements:
npm install
@@ -42,7 +50,7 @@ push_translations:
# Pulls translations from Transifex.
pull_translations:
tx pull -f --mode reviewed --language=$(transifex_langs)
tx pull -t -f --mode reviewed --languages=$(transifex_langs)
# This target is used by Travis.
validate-no-uncommitted-package-lock-changes:

View File

@@ -1,45 +1,96 @@
#########################
frontend-component-footer
=========================
#########################
|Build Status| |Coveralls| |npm_version| |npm_downloads| |license|
|semantic-release|
|Build Status| |Codecov| |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.
********
Overview
********
At this time, this component is hard-coded to match the legacy LMS site footer, including all of its links. As implemented, this component should probably 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 <src/index.jsx>`__ for an example
of how the SiteFooter component can be specified.
A generic footer for Open edX micro-frontend applications. It includes a logo and an optional language selector dropdown.
************
Requirements
------------
************
This component uses ``@edx/frontend-i18n``. Any containing app must provide ``@edx/frontend-i18n`` as a peer dependency, and be wrapped inside an ``IntlProvider`` element, whether or not your consuming application is actually localized. For a basic default locale (English) version, follow the ``IntlProvider`` example in the sample application in `src/index.jsx <src/index.jsx>`__.
This component uses ``@edx/frontend-platform`` services such as i18n, analytics, configuration, and the ``AppContext`` React component, and expects that it has been loaded into a micro-frontend that has been properly initialized via ``@edx/frontend-platform``'s ``initialize`` function. `Please visit the frontend template application to see an example. <https://github.com/openedx/frontend-template-application/blob/3355bb3a96232390e9056f35b06ffa8f105ed7ca/src/index.jsx>`_
Environment Variables
=====================
This component requires that the following environment variable be set by the consuming micro-frontend.
* ``LMS_BASE_URL`` - The URL of the LMS of your Open edX instance.
* ``LOGO_TRADEMARK_URL`` - This is a URL to a logo for use in the footer. This is a different environment variable than ``LOGO_URL`` (used in frontend-component-header) to accommodate sites that would like to have additional trademark information on a logo in the footer, such as a (tm) or (r) symbol.
************
Installation
************
To install this footer into your Open edX micro-frontend, run the following command in your MFE:
``npm i --save @edx/frontend-component-footer``
This will make the component available to be imported into your application.
*****
Usage
*****
This library has the following exports:
* ``(default)``: The footer as a React component.
* ``messages``: Internationalization messages suitable for use with `@edx/frontend-platform/i18n <https://edx.github.io/frontend-platform/module-Internationalization.html>`_
* ``dist/footer.scss``: A SASS file which contains style information for the component. It should be imported into the micro-frontend's own SCSS file.
<Footer /> component props
==========================
* onLanguageSelected: Provides the footer with an event handler for when the user selects a
language from its dropdown.
* supportedLanguages: An array of objects representing available languages. See example below for object shape.
Examples
========
Component Usage Example::
import Footer, { messages } from '@edx/frontend-component-footer';
...
<Footer
onLanguageSelected={(languageCode) => {/* set language */}}
supportedLanguages={[
{ label: 'English', value: 'en'},
{ label: 'Español', value: 'es' },
]}
/>
* `An example of minimal component and messages usage. <https://github.com/openedx/frontend-template-application/blob/3355bb3a96232390e9056f35b06ffa8f105ed7ca/src/index.jsx#L23>`_
* `An example of SCSS file usage. <https://github.com/openedx/frontend-template-application/blob/3cd5485bf387b8c479baf6b02bf59e3061dc3465/src/index.scss#L9>`_
***********
Development
-----------
***********
Start the dev server::
Install dependencies::
npm i && npm start
npm i
Build the component::
Start the development server::
npm run build
npm start
.. |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
Build a production distribution::
npm run build
.. |Build Status| image:: https://api.travis-ci.com/edx/frontend-component-footer.svg?branch=master
:target: https://travis-ci.com/edx/frontend-component-footer
.. |Codecov| image:: https://img.shields.io/codecov/c/github/edx/frontend-component-footer
:target: @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

3
babel.config.js Normal file
View File

@@ -0,0 +1,3 @@
const { createConfig } = require('@edx/frontend-build');
module.exports = createConfig('babel-preserve-modules');

View File

@@ -1,3 +0,0 @@
module.exports = {
extends: ['@commitlint/config-angular'],
};

View File

@@ -1,15 +0,0 @@
// This is the common Webpack config. The dev and prod Webpack configs both
// inherit config defined here.
const path = require('path');
module.exports = {
entry: {
app: path.resolve(__dirname, '../src/index.jsx'),
},
output: {
path: path.resolve(__dirname, '../dist'),
},
resolve: {
extensions: ['.js', '.jsx'],
},
};

View File

@@ -1,115 +0,0 @@
// This is the dev Webpack config. All settings here should prefer a fast build
// time at the expense of creating larger, unoptimized bundles.
const Merge = require('webpack-merge'); // eslint-disable-line import/no-extraneous-dependencies
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // eslint-disable-line import/no-extraneous-dependencies
const webpack = require('webpack'); // eslint-disable-line import/no-extraneous-dependencies
const commonConfig = require('./webpack.common.config.js');
module.exports = Merge.smart(commonConfig, {
mode: 'development',
entry: [
// enable react's custom hot dev client so we get errors reported in the browser
require.resolve('react-dev-utils/webpackHotDevClient'),
path.resolve(__dirname, '../src/index.jsx'),
],
module: {
// Specify file-by-file rules to Webpack. Some file-types need a particular kind of loader.
rules: [
// The babel-loader transforms newer ES2015+ syntax to older ES5 for older browsers.
// Babel is configured with the .babelrc file at the root of the project.
{
test: /\.(js|jsx)$/,
include: [
path.resolve(__dirname, '../src'),
],
loader: 'babel-loader',
options: {
// Caches result of loader to the filesystem. Future builds will attempt to read from the
// cache to avoid needing to run the expensive recompilation process on each run.
cacheDirectory: true,
},
},
// We are not extracting CSS from the javascript bundles in development because extracting
// prevents hot-reloading from working, it increases build time, and we don't care about
// flash-of-unstyled-content issues in development.
{
test: /(.scss|.css)$/,
use: [
'style-loader', // creates style nodes from JS strings
{
loader: 'css-loader', // translates CSS into CommonJS
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader', // compiles Sass to CSS
options: {
sourceMap: true,
includePaths: [
path.join(__dirname, '../node_modules'),
path.join(__dirname, '../src'),
],
},
},
],
},
// Webpack, by default, uses the url-loader for images and fonts that are required/included by
// files it processes, which just base64 encodes them and inlines them in the javascript
// bundles. This makes the javascript bundles ginormous and defeats caching so we will use the
// file-loader instead to copy the files directly to the output directory.
{
test: /\.(woff2?|ttf|svg|eot)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'file-loader',
},
{
test: /\.(jpe?g|png|gif|ico)(\?v=\d+\.\d+\.\d+)?$/,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
optimizationlevel: 7,
mozjpeg: {
progressive: true,
},
gifsicle: {
interlaced: false,
},
pngquant: {
quality: '65-90',
speed: 4,
},
},
},
],
},
],
},
// Specify additional processing or side-effects done on the Webpack output bundles as a whole.
plugins: [
// Generates an HTML file in the output directory.
new HtmlWebpackPlugin({
inject: true, // Appends script tags linking to the webpack bundles at the end of the body
template: path.resolve(__dirname, '../public/index.html'),
}),
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
}),
// when the --hot option is not passed in as part of the command
// the HotModuleReplacementPlugin has to be specified in the Webpack configuration
// https://webpack.js.org/configuration/dev-server/#devserver-hot
new webpack.HotModuleReplacementPlugin(),
],
// This configures webpack-dev-server which serves bundles from memory and provides live
// reloading.
devServer: {
host: '0.0.0.0',
port: 3000,
historyApiFallback: true,
hot: true,
inline: true,
},
});

View File

@@ -1,71 +0,0 @@
// This is the prod Webpack config. All settings here should prefer smaller,
// optimized bundles at the expense of a longer build time.
const Merge = require('webpack-merge'); // eslint-disable-line import/no-extraneous-dependencies
const commonConfig = require('./webpack.common.config.js');
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin'); // eslint-disable-line import/no-extraneous-dependencies
module.exports = Merge.smart(commonConfig, {
mode: 'production',
devtool: 'source-map',
entry: './src/lib/index.js',
output: {
path: path.resolve(__dirname, '../dist'),
library: 'frontend-component-footer',
libraryTarget: 'umd',
globalObject: 'typeof self !== \'undefined\' ? self : this',
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
react: path.resolve(__dirname, './node_modules/react'),
'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
},
},
externals: {
react: {
commonjs: 'react',
commonjs2: 'react',
amd: 'React',
root: 'React',
},
'react-dom': {
commonjs: 'react-dom',
commonjs2: 'react-dom',
amd: 'ReactDOM',
root: 'ReactDOM',
},
'@edx/frontend-i18n': {
commonjs: '@edx/frontend-i18n',
commonjs2: '@edx/frontend-i18n',
amd: '@edx/frontend-i18n',
root: '@edx/frontend-i18n',
},
'@edx/frontend-logging': {
commonjs: '@edx/frontend-logging',
commonjs2: '@edx/frontend-logging',
amd: '@edx/frontend-logging',
root: '@edx/frontend-logging',
},
},
plugins: [
// Cleans the dist directory before each build
new CleanWebpackPlugin(['dist'], {
root: path.join(__dirname, '../'),
}),
],
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: [
path.resolve(__dirname, '../src/lib'),
],
exclude: /(node_modules)/,
use: [
{ loader: 'babel-loader' },
],
},
],
},
});

33
example/index.jsx Normal file
View File

@@ -0,0 +1,33 @@
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import { initialize, getConfig, subscribe, APP_READY } from '@edx/frontend-platform';
import { AppContext, AppProvider } from '@edx/frontend-platform/react';
import Footer from '@edx/frontend-component-footer';
import './index.scss';
subscribe(APP_READY, () => {
ReactDOM.render(
<AppProvider>
<AppContext.Provider value={{
authenticatedUser: null,
config: getConfig(),
}}>
<Footer
onLanguageSelected={() => {}}
supportedLanguages={[
{ label: 'English', value: 'en' },
{ label: 'Español', value: 'es' },
]}
/>
</AppContext.Provider>
</AppProvider>,
document.getElementById('root'),
);
});
initialize({
messages: []
});

6
example/index.scss Normal file
View File

@@ -0,0 +1,6 @@
@import "@edx/brand/paragon/fonts";
@import "@edx/brand/paragon/variables";
@import "@edx/paragon/scss/core/core";
@import "@edx/brand/paragon/overrides";
@import "@edx/frontend-component-footer/footer";

7
jest.config.js Normal file
View File

@@ -0,0 +1,7 @@
const { createConfig } = require('@edx/frontend-build');
module.exports = createConfig('jest', {
setupFiles: [
'<rootDir>/src/setupTest.js',
],
});

8
openedx.yaml Normal file
View File

@@ -0,0 +1,8 @@
# openedx.yaml
---
owner: edx/fedx-team
tags:
- library
- component
- react

59730
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,119 +1,67 @@
{
"name": "@edx/frontend-component-footer",
"version": "1.0.0-semantically-released",
"description": "Site footer component for use when building edX frontend applications",
"main": "dist/main.js",
"module": "dist/main.js",
"description": "Footer component for use when building Open edX frontend applications",
"main": "dist/index.js",
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "NODE_ENV=production BABEL_ENV=production webpack --config=config/webpack.prod.config.js",
"build:stats": "NODE_ENV=production BABEL_ENV=production webpack --config=config/webpack.prod.config.js --profile --progress --json > stats.json",
"gc": "commit",
"commitmsg": "commitlint -e $GIT_PARAMS",
"coveralls": "cat ./coverage/lcov.info | coveralls",
"is-es5": "es-check es5 ./dist/*.js",
"i18n_extract": "BABEL_ENV=i18n babel src --quiet > /dev/null",
"lint": "eslint --ext .js --ext .jsx .",
"precommit": "npm run lint",
"prepublishOnly": "npm run build",
"semantic-release": "semantic-release",
"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",
"watch": "watch 'npm run build' ./src"
"build": "make build",
"i18n_extract": "BABEL_ENV=i18n fedx-scripts babel src --quiet > /dev/null",
"lint": "fedx-scripts eslint --ext .js --ext .jsx .",
"snapshot": "fedx-scripts jest --updateSnapshot",
"start": "fedx-scripts webpack-dev-server --progress",
"test": "fedx-scripts jest --coverage"
},
"files": [
"/dist"
],
"husky": {
"hooks": {
"pre-commit": "npm run lint"
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/edx/frontend-component-footer.git"
"url": "git+https://github.com/openedx/frontend-component-footer.git"
},
"author": "edX",
"license": "AGPL-3.0",
"bugs": {
"url": "https://github.com/edx/frontend-component-footer/issues"
"url": "https://github.com/openedx/frontend-component-footer/issues"
},
"homepage": "https://github.com/edx/frontend-component-footer#readme",
"homepage": "https://github.com/openedx/frontend-component-footer#readme",
"devDependencies": {
"@commitlint/cli": "^7.1.2",
"@commitlint/config-angular": "^6.0.2",
"@commitlint/prompt": "^6.0.2",
"@commitlint/prompt-cli": "^6.0.2",
"@edx/edx-bootstrap": "^2.2.1",
"@edx/frontend-i18n": "^2.1.0",
"@edx/frontend-logging": "^2.0.2",
"@fortawesome/fontawesome-svg-core": "^1.2.17",
"@fortawesome/free-brands-svg-icons": "^5.8.1",
"@fortawesome/free-regular-svg-icons": "^5.8.1",
"@fortawesome/free-solid-svg-icons": "^5.8.1",
"@fortawesome/react-fontawesome": "^0.1.4",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-react-intl": "^3.0.1",
"babel-plugin-rewire": "^1.2.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"clean-webpack-plugin": "^0.1.19",
"coveralls": "^3.0.0",
"css-loader": "^0.28.9",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"es-check": "^5.0.0",
"eslint": "^5.2.0",
"eslint-config-edx": "^4.0.4",
"eslint-plugin-jsx-a11y": "^6.1.2",
"file-loader": "^1.1.9",
"glob": "^7.1.3",
"html-webpack-plugin": "^3.2.0",
"husky": "^0.14.3",
"image-webpack-loader": "^4.2.0",
"jest": "23.6.0",
"node-sass": "^4.7.2",
"prop-types": "^15.5.10",
"react": "^16.4.2",
"react-dev-utils": "^5.0.0",
"react-dom": "^16.2.0",
"react-test-renderer": "^16.6.0",
"reactifex": "^1.1.1",
"sass-loader": "^6.0.6",
"semantic-release": "^15.1.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",
"webpack-merge": "^4.2.1"
"@edx/brand": "npm:@edx/brand-openedx@1.2.0",
"@edx/browserslist-config": "^1.1.1",
"@edx/frontend-build": "12.4.19",
"@edx/frontend-platform": "^3.0.1",
"@edx/paragon": "^20.19.0",
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.7",
"husky": "7.0.4",
"prop-types": "15.8.1",
"react": "16.14.0",
"react-dom": "16.14.0",
"react-redux": "7.2.9",
"react-router-dom": "5.3.4",
"react-test-renderer": "16.14.0",
"reactifex": "1.1.1",
"redux": "4.2.1",
"semantic-release": "19.0.5"
},
"dependencies": {
"query-string": "^5.1.1"
"@fortawesome/fontawesome-svg-core": "6.2.1",
"@fortawesome/free-brands-svg-icons": "6.2.1",
"@fortawesome/free-regular-svg-icons": "6.2.1",
"@fortawesome/free-solid-svg-icons": "6.2.1",
"@fortawesome/react-fontawesome": "0.2.0"
},
"peerDependencies": {
"@edx/frontend-i18n": "^2.1.0",
"@edx/frontend-logging": "^2.0.2",
"@edx/paragon": "^4.2.4",
"@edx/frontend-platform": "^2.0.0 || ^3.0.0",
"prop-types": "^15.5.10",
"react": "^16.4.2",
"react-dom": "^16.2.0"
},
"jest": {
"setupFiles": [
"./src/tests/setupTest.js"
],
"collectCoverageFrom": [
"src/lib/**/*.{js,jsx}",
"!src/tests/setupTest.js",
"!src/index.js",
"!**/node_modules/**",
"!**/tests/**"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|scss)$": "identity-obj-proxy"
}
"react": "^16.9.0",
"react-dom": "^16.9.0"
}
}

View File

@@ -1,9 +1,9 @@
<!doctype html>
<html lang="en-us">
<html lang="en-us" dir="ltr">
<head>
<title>Footer | edX</title>
<title>Footer</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="root"></div>

33
renovate.json Normal file
View File

@@ -0,0 +1,33 @@
{
"extends": [
"config:base",
"schedule:weekly",
":automergeLinters",
":automergeMinor",
":automergeTesters",
":enableVulnerabilityAlerts",
":rebaseStalePrs",
":semanticCommits",
":updateNotScheduled"
],
"packageRules": [
{
"matchDepTypes": [
"devDependencies"
],
"matchUpdateTypes": [
"lockFileMaintenance",
"minor",
"patch",
"pin"
],
"automerge": true
},
{
"matchPackagePatterns": ["@edx"],
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
}
],
"timezone": "America/New_York"
}

5
src/_footer.scss Normal file
View File

@@ -0,0 +1,5 @@
$gray-footer: #fcfcfc !default;
.footer {
background-color: $gray-footer;
}

95
src/components/Footer.jsx Normal file
View File

@@ -0,0 +1,95 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { ensureConfig } from '@edx/frontend-platform/config';
import { AppContext } from '@edx/frontend-platform/react';
import messages from './Footer.messages';
import LanguageSelector from './LanguageSelector';
ensureConfig([
'LMS_BASE_URL',
'LOGO_TRADEMARK_URL',
], 'Footer component');
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,
};
sendTrackEvent(eventName, properties);
}
render() {
const {
supportedLanguages,
onLanguageSelected,
logo,
intl,
} = this.props;
const showLanguageSelector = supportedLanguages.length > 0 && onLanguageSelected;
const { config } = this.context;
return (
<footer
role="contentinfo"
className="footer d-flex border-top py-3 px-4"
>
<div className="container-fluid d-flex">
<a
className="d-block"
href={config.LMS_BASE_URL}
aria-label={intl.formatMessage(messages['footer.logo.ariaLabel'])}
>
<img
style={{ maxHeight: 45 }}
src={logo || config.LOGO_TRADEMARK_URL}
alt={intl.formatMessage(messages['footer.logo.altText'])}
/>
</a>
<div className="flex-grow-1" />
{showLanguageSelector && (
<LanguageSelector
options={supportedLanguages}
onSubmit={onLanguageSelected}
/>
)}
</div>
</footer>
);
}
}
SiteFooter.contextType = AppContext;
SiteFooter.propTypes = {
intl: intlShape.isRequired,
logo: PropTypes.string,
onLanguageSelected: PropTypes.func,
supportedLanguages: PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
})),
};
SiteFooter.defaultProps = {
logo: undefined,
onLanguageSelected: undefined,
supportedLanguages: [],
};
export default injectIntl(SiteFooter);
export { EVENT_NAMES };

View File

@@ -0,0 +1,156 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
'footer.socialLinks.srText.facebook': {
id: 'footer.socialLinks.srText.facebook',
defaultMessage: 'Like edX on Facebook',
description: 'This is screenreader text for the edX Facebook social media link in the footer.',
},
'footer.socialLinks.srText.twitter': {
id: 'footer.socialLinks.srText.twitter',
defaultMessage: 'Follow edX on Twitter',
description: 'This is screenreader text for the edX Twitter social media link in the footer.',
},
'footer.socialLinks.srText.youtube': {
id: 'footer.socialLinks.srText.youtube',
defaultMessage: 'Subscribe to the edX YouTube channel',
description: 'This is screenreader text for the edX YouTube social media link in the footer.',
},
'footer.socialLinks.srText.linkedin': {
id: 'footer.socialLinks.srText.linkedin',
defaultMessage: 'Follow edX on LinkedIn',
description: 'This is screenreader text for the edX LinkedIn social media link in the footer.',
},
'footer.socialLinks.srText.reddit': {
id: 'footer.socialLinks.srText.reddit',
defaultMessage: 'Subscribe to the edX subreddit',
description: 'This is screenreader text for the edX reddit social media link in the footer.',
},
'footer.languageForm.select.label': {
id: 'footer.languageForm.select.label',
defaultMessage: 'Choose Language',
description: 'The label for the laguage select part of the language selection form.',
},
'footer.languageForm.submit.label': {
id: 'footer.languageForm.submit.label',
defaultMessage: 'Apply',
description: 'The label for button to submit the language selection form.',
},
'footer.edxLinks.about': {
id: 'footer.edxLinks.about',
defaultMessage: 'About',
description: 'The label for the link to the about edX page.',
},
'footer.edxLinks.business': {
id: 'footer.edxLinks.business',
defaultMessage: 'edX for Business',
description: 'The label for the link to the edX for business page.',
},
'footer.edxLinks.affiliates': {
id: 'footer.edxLinks.affiliates',
defaultMessage: 'Affiliates',
description: 'The label for the link to the edX affiliates page.',
},
'footer.edxLinks.openEdx': {
id: 'footer.edxLinks.openEdx',
defaultMessage: 'Open edX',
description: 'The label for the link to the open edX site.',
},
'footer.edxLinks.careers': {
id: 'footer.edxLinks.careers',
defaultMessage: 'Careers',
description: 'The label for the link to the edX Careers page.',
},
'footer.edxLinks.news': {
id: 'footer.edxLinks.news',
defaultMessage: 'News',
description: 'The label for the link to the edX news page.',
},
'footer.legalLinks.heading': {
id: 'footer.legalLinks.heading',
defaultMessage: 'Legal',
description: 'Heading for the legal links section of the footer.',
},
'footer.legalLinks.termsOfService': {
id: 'footer.legalLinks.termsOfService',
defaultMessage: 'Terms of Service & Honor Code',
description: 'The label for the link to the edX terms of service page.',
},
'footer.legalLinks.privacyPolicy': {
id: 'footer.legalLinks.privacyPolicy',
defaultMessage: 'Privacy Policy',
description: 'The label for the link to the edX privacy policy page.',
},
'footer.legalLinks.a11yPolicy': {
id: 'footer.legalLinks.a11yPolicy',
defaultMessage: 'Accessibility Policy',
description: 'The label for the link to the edX accessibility policy page.',
},
'footer.legalLinks.trademarkPolicy': {
id: 'footer.legalLinks.trademarkPolicy',
defaultMessage: 'Trademark Policy',
description: 'The label for the link to the edX trademark policy page.',
},
'footer.legalLinks.sitemap': {
id: 'footer.legalLinks.sitemap',
defaultMessage: 'Sitemap',
description: 'The label for the link to the edX sitemap page.',
},
'footer.connectLinks.heading': {
id: 'footer.connectLinks.heading',
defaultMessage: 'Connect',
description: 'Heading for the connect links section of the footer.',
},
'footer.connectLinks.blog': {
id: 'footer.connectLinks.blog',
defaultMessage: 'Blog',
description: 'The label for the link to the edX blog.',
},
'footer.connectLinks.contact': {
id: 'footer.connectLinks.contact',
defaultMessage: 'Contact Us',
description: 'The label for the link to the contact edX page.',
},
'footer.connectLinks.help': {
id: 'footer.connectLinks.help',
defaultMessage: 'Help Center',
description: 'The label for the link to the edX help center.',
},
'footer.connectLinks.mediaKit': {
id: 'footer.connectLinks.mediaKit',
defaultMessage: 'Media Kit',
description: 'The label for the link to the edX media kit page.',
},
'footer.connectLinks.donate': {
id: 'footer.connectLinks.donate',
defaultMessage: 'Donate',
description: 'The label for the link to the edX donation page.',
},
'footer.mobileApp.apple': {
id: 'footer.mobileApp.apple',
defaultMessage: 'Download the edX mobile app from the Apple App Store',
description: 'The label for the link to download the apple version of the edX app.',
},
'footer.mobileApp.google': {
id: 'footer.mobileApp.google',
defaultMessage: 'Download the edX mobile app from Google Play',
description: 'The label for the link to download the google version of the edX app.',
},
'footer.logo.altText': {
id: 'footer.logo.altText',
defaultMessage: 'Powered by Open edX',
description: 'alt text for the footer logo.',
},
'footer.logo.ariaLabel': {
id: 'footer.logo.ariaLabel',
defaultMessage: 'edX Home',
description: 'aria-label for the footer logo.',
},
'footer.ariaLabel': {
id: 'footer.ariaLabel',
defaultMessage: 'Page Footer',
description: 'aria-label for the footer component',
},
});
export default messages;

View File

@@ -0,0 +1,96 @@
/* eslint-disable react/prop-types */
import React, { useMemo } from 'react';
import renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { AppContext } from '@edx/frontend-platform/react';
import Footer from './Footer';
const FooterWithContext = ({ locale = 'es' }) => {
const contextValue = useMemo(() => ({
authenticatedUser: null,
config: {
LOGO_TRADEMARK_URL: process.env.LOGO_TRADEMARK_URL,
LMS_BASE_URL: process.env.LMS_BASE_URL,
},
}), []);
return (
<IntlProvider locale={locale}>
<AppContext.Provider
value={contextValue}
>
<Footer />
</AppContext.Provider>
</IntlProvider>
);
};
const FooterWithLanguageSelector = ({ languageSelected = () => {} }) => {
const contextValue = useMemo(() => ({
authenticatedUser: null,
config: {
LOGO_TRADEMARK_URL: process.env.LOGO_TRADEMARK_URL,
LMS_BASE_URL: process.env.LMS_BASE_URL,
},
}), []);
return (
<IntlProvider locale="en">
<AppContext.Provider
value={contextValue}
>
<Footer
onLanguageSelected={languageSelected}
supportedLanguages={[
{ label: 'English', value: 'en' },
{ label: 'Español', value: 'es' },
]}
/>
</AppContext.Provider>
</IntlProvider>
);
};
describe('<Footer />', () => {
describe('renders correctly', () => {
it('renders without a language selector', () => {
const tree = renderer
.create(<FooterWithContext locale="en" />)
.toJSON();
expect(tree).toMatchSnapshot();
});
it('renders without a language selector in es', () => {
const tree = renderer
.create(<FooterWithContext locale="es" />)
.toJSON();
expect(tree).toMatchSnapshot();
});
it('renders with a language selector', () => {
const tree = renderer
.create(<FooterWithLanguageSelector />)
.toJSON();
expect(tree).toMatchSnapshot();
});
});
describe('handles language switching', () => {
it('calls onLanguageSelected prop when a language is changed', () => {
const mockHandleLanguageSelected = jest.fn();
const wrapper = mount(<FooterWithLanguageSelector languageSelected={mockHandleLanguageSelected} />);
wrapper.find('form').simulate('submit', {
target: {
elements: {
'site-footer-language-select': {
value: 'es',
},
},
},
});
expect(mockHandleLanguageSelected).toHaveBeenCalledWith('es');
});
});
});

View File

@@ -0,0 +1,58 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
const LanguageSelector = ({
intl, options, onSubmit, ...props
}) => {
const handleSubmit = (e) => {
e.preventDefault();
const languageCode = e.target.elements['site-footer-language-select'].value;
onSubmit(languageCode);
};
return (
<form
className="form-inline"
onSubmit={handleSubmit}
{...props}
>
<div className="form-group">
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label htmlFor="site-footer-language-select" className="d-inline-block m-0">
<FormattedMessage
id="footer.languageForm.select.label"
defaultMessage="Choose Language"
description="The label for the laguage select part of the language selection form."
/>
</label>
<select
id="site-footer-language-select"
className="form-control-sm mx-2"
name="site-footer-language-select"
defaultValue={intl.locale}
>
{options.map(({ value, label }) => <option key={value} value={value}>{label}</option>)}
</select>
<button className="btn btn-outline-primary btn-sm" type="submit">
<FormattedMessage
id="footer.languageForm.submit.label"
defaultMessage="Apply"
description="The label for button to submit the language selection form."
/>
</button>
</div>
</form>
);
};
LanguageSelector.propTypes = {
intl: intlShape.isRequired,
onSubmit: PropTypes.func.isRequired,
options: PropTypes.arrayOf(PropTypes.shape({
value: PropTypes.string,
label: PropTypes.string,
})).isRequired,
};
export default injectIntl(LanguageSelector);

View File

@@ -0,0 +1,129 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<Footer /> renders correctly renders with a language selector 1`] = `
<footer
className="footer d-flex border-top py-3 px-4"
role="contentinfo"
>
<div
className="container-fluid d-flex"
>
<a
aria-label="edX Home"
className="d-block"
href="http://localhost:18000"
>
<img
alt="Powered by Open edX"
src="https://edx-cdn.org/v3/default/logo-trademark.svg"
style={
Object {
"maxHeight": 45,
}
}
/>
</a>
<div
className="flex-grow-1"
/>
<form
className="form-inline"
onSubmit={[Function]}
>
<div
className="form-group"
>
<label
className="d-inline-block m-0"
htmlFor="site-footer-language-select"
>
Choose Language
</label>
<select
className="form-control-sm mx-2"
defaultValue="en"
id="site-footer-language-select"
name="site-footer-language-select"
>
<option
value="en"
>
English
</option>
<option
value="es"
>
Español
</option>
</select>
<button
className="btn btn-outline-primary btn-sm"
type="submit"
>
Apply
</button>
</div>
</form>
</div>
</footer>
`;
exports[`<Footer /> renders correctly renders without a language selector 1`] = `
<footer
className="footer d-flex border-top py-3 px-4"
role="contentinfo"
>
<div
className="container-fluid d-flex"
>
<a
aria-label="edX Home"
className="d-block"
href="http://localhost:18000"
>
<img
alt="Powered by Open edX"
src="https://edx-cdn.org/v3/default/logo-trademark.svg"
style={
Object {
"maxHeight": 45,
}
}
/>
</a>
<div
className="flex-grow-1"
/>
</div>
</footer>
`;
exports[`<Footer /> renders correctly renders without a language selector in es 1`] = `
<footer
className="footer d-flex border-top py-3 px-4"
role="contentinfo"
>
<div
className="container-fluid d-flex"
>
<a
aria-label="edX Home"
className="d-block"
href="http://localhost:18000"
>
<img
alt="Powered by Open edX"
src="https://edx-cdn.org/v3/default/logo-trademark.svg"
style={
Object {
"maxHeight": 45,
}
}
/>
</a>
<div
className="flex-grow-1"
/>
</div>
</footer>
`;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -1,31 +1,27 @@
import arMessages from './messages/ar.json';
import caMessages from './messages/ca.json';
// no need to import en messages-- they are in the defaultMessage field
import es419Messages from './messages/es_419.json';
import frMessages from './messages/fr.json';
import es419Messages from './messages/es_419.json';
import zhcnMessages from './messages/zh_CN.json';
import heMessages from './messages/he.json';
import idMessages from './messages/id.json';
import kokrMessages from './messages/ko_kr.json';
import plMessages from './messages/pl.json';
import ptbrMessages from './messages/pt_br.json';
import ruMessages from './messages/ru.json';
import thMessages from './messages/th.json';
import ptMessages from './messages/pt.json';
import itMessages from './messages/it.json';
import ukMessages from './messages/uk.json';
import deMessages from './messages/de.json';
import ruMessages from './messages/ru.json';
import hiMessages from './messages/hi.json';
import frCAMessages from './messages/fr_CA.json';
// no need to import en messages-- they are in the defaultMessage field
const messages = {
ar: arMessages,
'es-419': es419Messages,
fr: frMessages,
'zh-cn': zhcnMessages,
ca: caMessages,
he: heMessages,
id: idMessages,
'ko-kr': kokrMessages,
pl: plMessages,
'pt-br': ptbrMessages,
pt: ptMessages,
it: itMessages,
de: deMessages,
hi: hiMessages,
'fr-ca': frCAMessages,
ru: ruMessages,
th: thMessages,
uk: ukMessages,
};

View File

@@ -1 +0,0 @@
{}

View File

@@ -1 +0,0 @@
{}

5
src/index.js Normal file
View File

@@ -0,0 +1,5 @@
import Footer, { EVENT_NAMES } from './components/Footer';
import messages from './i18n/index';
export default Footer;
export { messages, EVENT_NAMES };

View File

@@ -1,183 +0,0 @@
import React from 'react';
import { render } from 'react-dom';
/* eslint-disable import/no-extraneous-dependencies */
import {
faFacebookSquare,
faTwitterSquare,
faYoutubeSquare,
faLinkedin,
faRedditSquare,
} from '@fortawesome/free-brands-svg-icons';
import { faLanguage } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
/* eslint-enable import/no-extraneous-dependencies */
import SiteFooter from './lib';
import './index.scss';
import FooterLogo from './edx-footer.png';
const edXLinks = [
{
title: 'About',
url: 'https://www.example.com/about-us',
},
{
title: 'edX for Business',
url: 'https://business.edx.org',
queryParams: { utm_test: 'utm_test_value' },
},
{
title: 'Affiliates',
url: 'https://www.example.com/affiliate-program',
},
{
title: 'Open edX',
url: 'https://www.example.com/open',
},
{
title: 'Careers',
url: 'https://www.example.com/careers',
},
{
title: 'News',
url: 'https://www.example.com/news-announcements',
},
];
const legalLinks = [
{
title: 'Terms of Service & Honor Code',
url: 'https://www.example.com/terms-of-service',
},
{
title: 'Privacy Policy',
url: 'https://www.example.com/privacy-policy',
},
{
title: 'Accessibility Policy',
url: 'https://www.example.com/accessibility',
},
{
title: 'Trademark Policy',
url: 'https://www.example.com/trademarks',
},
{
title: 'Sitemap',
url: 'https://www.example.com/sitemap',
},
];
const connectLinks = [
{
title: 'Blog',
url: 'https://www.example.com/blog',
},
{
title: 'Contact Us',
url: 'https://www.example.com/contact',
},
{
title: 'Help Center',
url: 'https://www.example.com/support',
},
{
title: 'Media Kit',
url: 'https://www.example.com/media-kit',
},
{
title: 'Donate',
url: 'https://www.example.com/donate',
},
];
const socialLinks = [
{
title: 'Facebook',
url: 'https://www.facebook.com',
icon: <FontAwesomeIcon icon={faFacebookSquare} className="social-icon" size="2x" />,
screenReaderText: 'Like edX on Facebook',
},
{
title: 'Twitter',
url: 'https://www.twitter.com',
icon: <FontAwesomeIcon icon={faTwitterSquare} className="social-icon" size="2x" />,
screenReaderText: 'Follow edX on Twitter',
},
{
title: 'Youtube',
url: 'https://www.youtube.com',
icon: <FontAwesomeIcon icon={faYoutubeSquare} className="social-icon" size="2x" />,
screenReaderText: 'Subscribe to the edX YouTube channel',
},
{
title: 'LinkedIn',
url: 'https://www.linkedin.com',
icon: <FontAwesomeIcon icon={faLinkedin} className="social-icon" size="2x" />,
screenReaderText: 'Follow edX on LinkedIn',
},
{
title: 'Reddit',
url: 'https://reddit.com',
icon: <FontAwesomeIcon icon={faRedditSquare} className="social-icon" size="2x" />,
screenReaderText: 'Subscribe to the edX subreddit',
},
];
const App = () => (
<SiteFooter
siteLogo={{
src: FooterLogo,
altText: 'edx Logo',
ariaLabel: 'edX Home',
}}
ariaLabel="Page Footer"
marketingSiteBaseUrl="https://www.example.com"
appleAppStore={{
url: 'https://store.apple.com',
altText: 'Download the edX mobile app from the Apple App Store',
}}
googlePlay={{
url: 'https://play.google.com',
altText: 'Download the edX mobile app from Google Play',
}}
handleAllTrackEvents={() => {}}
linkSectionOne={{
title: 'edX',
linkList: edXLinks,
}}
linkSectionTwo={{
title: 'Legal',
linkList: legalLinks,
}}
linkSectionThree={{
title: 'Connect',
linkList: connectLinks,
}}
socialLinks={socialLinks}
supportedLanguages={[
{
label: 'English',
value: 'en',
}, {
label: 'español',
value: 'es-419',
},
]}
languageForm={{
activeLanguage: 'en',
screenReaderLabel: 'Choose Language',
submitLabel: 'Apply',
icon: <FontAwesomeIcon icon={faLanguage} size="2x" className="text-primary" />,
onLanguageSelected: () => {},
}}
copyright="© 20122019 edX Inc."
trademark={(
<React.Fragment>EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a></React.Fragment>
)}
/>
);
render(<App />, document.getElementById('root'));

View File

@@ -1,4 +0,0 @@
@import "~@edx/edx-bootstrap/scss/edx/theme";
@import "~bootstrap/scss/bootstrap";
@import './lib/scss/_site-footer.scss';

View File

@@ -1,348 +0,0 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import {
faFacebookSquare,
faTwitterSquare,
faYoutubeSquare,
faLinkedin,
faRedditSquare,
} from '@fortawesome/free-brands-svg-icons';
import { faLanguage } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import FooterLogo from '../../../edx-footer.png';
import SiteFooter, { EVENT_NAMES } from './index';
const edXLinks = [
{
title: 'About',
url: 'https://www.example.com/about-us',
},
{
title: 'edX for Business',
url: 'https://business.edx.org',
queryParams: { utm_test: 'utm_test_value' },
},
{
title: 'Affiliates',
url: 'https://www.example.com/affiliate-program',
},
{
title: 'Open edX',
url: 'https://www.example.com/open',
},
{
title: 'Careers',
url: 'https://www.example.com/careers',
},
{
title: 'News',
url: 'https://www.example.com/news-announcements',
},
];
const legalLinks = [
{
title: 'Terms of Service & Honor Code',
url: 'https://www.example.com/terms-of-service',
},
{
title: 'Privacy Policy',
url: 'https://www.example.com/privacy-policy',
},
{
title: 'Accessibility Policy',
url: 'https://www.example.com/accessibility',
},
{
title: 'Trademark Policy',
url: 'https://www.example.com/trademarks',
},
{
title: 'Sitemap',
url: 'https://www.example.com/sitemap',
},
];
const connectLinks = [
{
title: 'Blog',
url: 'https://www.example.com/blog',
},
{
title: 'Contact Us',
url: 'https://www.example.com/contact',
},
{
title: 'Help Center',
url: 'https://www.example.com/support',
},
{
title: 'Media Kit',
url: 'https://www.example.com/media-kit',
},
{
title: 'Donate',
url: 'https://www.example.com/donate',
},
];
const socialLinks = [
{
title: 'Facebook',
url: 'https://www.facebook.com',
icon: <FontAwesomeIcon icon={faFacebookSquare} className="social-icon" size="2x" />,
screenReaderText: 'Like edX on Facebook',
},
{
title: 'Twitter',
url: 'https://www.twitter.com',
icon: <FontAwesomeIcon icon={faTwitterSquare} className="social-icon" size="2x" />,
screenReaderText: 'Follow edX on Twitter',
},
{
title: 'Youtube',
url: 'https://www.youtube.com',
icon: <FontAwesomeIcon icon={faYoutubeSquare} className="social-icon" size="2x" />,
screenReaderText: 'Subscribe to the edX YouTube channel',
},
{
title: 'LinkedIn',
url: 'https://www.linkedin.com',
icon: <FontAwesomeIcon icon={faLinkedin} className="social-icon" size="2x" />,
screenReaderText: 'Follow edX on LinkedIn',
},
{
title: 'Reddit',
url: 'https://reddit.com',
icon: <FontAwesomeIcon icon={faRedditSquare} className="social-icon" size="2x" />,
screenReaderText: 'Subscribe to the edX subreddit',
},
];
const supportedLanguages = [
{
label: 'English',
value: 'en',
}, {
label: 'español',
value: 'es-419',
},
];
const languageForm = {
activeLanguage: 'en',
screenReaderLabel: 'Choose Language',
submitLabel: 'Apply',
icon: <FontAwesomeIcon icon={faLanguage} size="2x" className="text-primary" />,
onLanguageSelected: () => {},
};
const completeSiteFooterComponent = mockHandleAllTrackEvents =>
(
<SiteFooter
siteLogo={{
src: FooterLogo,
altText: 'edx Logo',
ariaLabel: 'edX Home',
}}
ariaLabel="Page Footer"
marketingSiteBaseUrl="https://www.example.com"
appleAppStore={{
url: 'https://store.apple.com',
altText: 'Download the edX mobile app from the Apple App Store',
}}
googlePlay={{
url: 'https://play.google.com',
altText: 'Download the edX mobile app from Google Play',
}}
handleAllTrackEvents={mockHandleAllTrackEvents}
linkSectionOne={{
title: 'edX',
linkList: edXLinks,
}}
linkSectionTwo={{
title: 'Legal',
linkList: legalLinks,
}}
linkSectionThree={{
title: 'Connect',
linkList: connectLinks,
}}
socialLinks={socialLinks}
supportedLanguages={supportedLanguages}
languageForm={languageForm}
copyright="© 20122019 edX Inc."
trademark={(
<React.Fragment>EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a></React.Fragment>
)}
/>
);
describe('<SiteFooter />', () => {
describe('renders correctly', () => {
it('renders with social and mobile links', () => {
const mockHandleAllTrackEvents = jest.fn();
const tree = renderer
.create(completeSiteFooterComponent(mockHandleAllTrackEvents))
.toJSON();
expect(tree).toMatchSnapshot();
});
it('does not render social links', () => {
const tree = renderer
.create((
<SiteFooter
siteLogo={{
src: FooterLogo,
altText: 'edx Logo',
ariaLabel: 'edX Home',
}}
ariaLabel="Page Footer"
marketingSiteBaseUrl="https://www.example.com"
appleAppStore={{
url: 'https://store.apple.com',
altText: 'Download the edX mobile app from the Apple App Store',
}}
googlePlay={{
url: 'https://play.google.com',
altText: 'Download the edX mobile app from Google Play',
}}
handleAllTrackEvents={jest.fn()}
linkSectionOne={{
title: 'edX',
linkList: edXLinks,
}}
linkSectionTwo={{
title: 'Legal',
linkList: legalLinks,
}}
linkSectionThree={{
title: 'Connect',
linkList: connectLinks,
}}
supportedLanguages={supportedLanguages}
languageForm={languageForm}
copyright="© 20122019 edX Inc."
trademark={(
<React.Fragment>EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a></React.Fragment>
)}
/>
)).toJSON();
expect(tree).toMatchSnapshot();
});
it('does not render mobile links', () => {
const tree = renderer
.create((
<SiteFooter
siteLogo={{
src: FooterLogo,
altText: 'edx Logo',
ariaLabel: 'edX Home',
}}
ariaLabel="Page Footer"
marketingSiteBaseUrl="https://www.example.com"
appleAppStore={{
url: 'https://store.apple.com',
altText: 'Download the edX mobile app from the Apple App Store',
}}
googlePlay={{
url: 'https://play.google.com',
altText: 'Download the edX mobile app from Google Play',
}}
handleAllTrackEvents={jest.fn()}
linkSectionOne={{
title: 'edX',
linkList: edXLinks,
}}
linkSectionTwo={{
title: 'Legal',
linkList: legalLinks,
}}
linkSectionThree={{
title: 'Connect',
linkList: connectLinks,
}}
socialLinks={socialLinks}
supportedLanguages={supportedLanguages}
languageForm={languageForm}
copyright="© 20122019 edX Inc."
trademark={(
<React.Fragment>EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a></React.Fragment>
)}
showMobileLinks={false}
/>
)).toJSON();
expect(tree).toMatchSnapshot();
});
it('does not render language selector', () => {
const tree = renderer
.create((
<SiteFooter
siteLogo={{
src: FooterLogo,
altText: 'edx Logo',
ariaLabel: 'edX Home',
}}
ariaLabel="Page Footer"
marketingSiteBaseUrl="https://www.example.com"
appleAppStore={{
url: 'https://store.apple.com',
altText: 'Download the edX mobile app from the Apple App Store',
}}
googlePlay={{
url: 'https://play.google.com',
altText: 'Download the edX mobile app from Google Play',
}}
handleAllTrackEvents={jest.fn()}
linkSectionOne={{
title: 'edX',
linkList: edXLinks,
}}
linkSectionTwo={{
title: 'Legal',
linkList: legalLinks,
}}
linkSectionThree={{
title: 'Connect',
linkList: connectLinks,
}}
socialLinks={socialLinks}
supportedLanguages={supportedLanguages}
copyright="© 20122019 edX Inc."
trademark={(
<React.Fragment>EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a></React.Fragment>
)}
/>
)).toJSON();
expect(tree).toMatchSnapshot();
});
});
describe('handles analytics', () => {
it('calls handleAllTrackEvents prop when external links clicked', () => {
const mockHandleAllTrackEvents = jest.fn();
const footer = mount((completeSiteFooterComponent(mockHandleAllTrackEvents)));
const externalLinks = footer.find("a[target='_blank']");
expect(externalLinks.length).toEqual(socialLinks.length + 2);
externalLinks.forEach((externalLink) => {
const callIndex = mockHandleAllTrackEvents.mock.calls.length;
externalLink.simulate('click');
expect(mockHandleAllTrackEvents.mock.calls[callIndex]).toEqual([
EVENT_NAMES.FOOTER_LINK,
{
category: 'outbound_link',
label: externalLink.prop('href'),
},
]);
});
});
});
});

View File

@@ -1,1503 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<SiteFooter /> renders correctly does not render language selector 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="edX Home"
href="https://www.example.com"
>
<img
alt="edx Logo"
src="test-file-stub"
/>
</a>
</div>
<div
className="area-2"
>
<h2>
edX
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://business.edx.org/?utm_test=utm_test_value"
>
edX for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open edX
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4"
>
<li>
<a
href="https://www.facebook.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Facebook"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-facebook-square fa-w-14 fa-2x social-icon"
data-icon="facebook-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Like edX on Facebook
</span>
</a>
</li>
<li>
<a
href="https://www.twitter.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Twitter"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-twitter-square fa-w-14 fa-2x social-icon"
data-icon="twitter-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on Twitter
</span>
</a>
</li>
<li>
<a
href="https://www.youtube.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Youtube"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-youtube-square fa-w-14 fa-2x social-icon"
data-icon="youtube-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M186.8 202.1l95.2 54.1-95.2 54.1V202.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-42 176.3s0-59.6-7.6-88.2c-4.2-15.8-16.5-28.2-32.2-32.4C337.9 128 224 128 224 128s-113.9 0-142.2 7.7c-15.7 4.2-28 16.6-32.2 32.4-7.6 28.5-7.6 88.2-7.6 88.2s0 59.6 7.6 88.2c4.2 15.8 16.5 27.7 32.2 31.9C110.1 384 224 384 224 384s113.9 0 142.2-7.7c15.7-4.2 28-16.1 32.2-31.9 7.6-28.5 7.6-88.1 7.6-88.1z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX YouTube channel
</span>
</a>
</li>
<li>
<a
href="https://www.linkedin.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="LinkedIn"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-linkedin fa-w-14 fa-2x social-icon"
data-icon="linkedin"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on LinkedIn
</span>
</a>
</li>
<li>
<a
href="https://reddit.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Reddit"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-reddit-square fa-w-14 fa-2x social-icon"
data-icon="reddit-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX subreddit
</span>
</a>
</li>
</ul>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5"
>
<li>
<a
href="https://store.apple.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from the Apple App Store"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a
href="https://play.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from Google Play"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
<p>
© 20122019 edX Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</p>
</div>
</div>
</footer>
`;
exports[`<SiteFooter /> renders correctly does not render mobile links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="edX Home"
href="https://www.example.com"
>
<img
alt="edx Logo"
src="test-file-stub"
/>
</a>
<div
className="i18n d-flex mt-2"
>
<form
className="d-flex align-items-start"
onSubmit={[Function]}
>
<label
htmlFor="site-footer-language-select"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-language fa-w-20 fa-2x text-primary"
data-icon="language"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 640 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z"
fill="currentColor"
style={Object {}}
/>
</svg>
<div
className="sr-only"
>
Choose Language
</div>
</label>
<select
className="mx-2 mt-1"
defaultValue="en"
id="site-footer-language-select"
name="site-footer-language-select"
>
<option
value="en"
>
English
</option>
<option
value="es-419"
>
español
</option>
</select>
<button
className="mt-1"
type="submit"
>
Apply
</button>
</form>
</div>
</div>
<div
className="area-2"
>
<h2>
edX
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://business.edx.org/?utm_test=utm_test_value"
>
edX for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open edX
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4"
>
<li>
<a
href="https://www.facebook.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Facebook"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-facebook-square fa-w-14 fa-2x social-icon"
data-icon="facebook-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Like edX on Facebook
</span>
</a>
</li>
<li>
<a
href="https://www.twitter.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Twitter"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-twitter-square fa-w-14 fa-2x social-icon"
data-icon="twitter-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on Twitter
</span>
</a>
</li>
<li>
<a
href="https://www.youtube.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Youtube"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-youtube-square fa-w-14 fa-2x social-icon"
data-icon="youtube-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M186.8 202.1l95.2 54.1-95.2 54.1V202.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-42 176.3s0-59.6-7.6-88.2c-4.2-15.8-16.5-28.2-32.2-32.4C337.9 128 224 128 224 128s-113.9 0-142.2 7.7c-15.7 4.2-28 16.6-32.2 32.4-7.6 28.5-7.6 88.2-7.6 88.2s0 59.6 7.6 88.2c4.2 15.8 16.5 27.7 32.2 31.9C110.1 384 224 384 224 384s113.9 0 142.2-7.7c15.7-4.2 28-16.1 32.2-31.9 7.6-28.5 7.6-88.1 7.6-88.1z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX YouTube channel
</span>
</a>
</li>
<li>
<a
href="https://www.linkedin.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="LinkedIn"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-linkedin fa-w-14 fa-2x social-icon"
data-icon="linkedin"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on LinkedIn
</span>
</a>
</li>
<li>
<a
href="https://reddit.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Reddit"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-reddit-square fa-w-14 fa-2x social-icon"
data-icon="reddit-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX subreddit
</span>
</a>
</li>
</ul>
<p>
© 20122019 edX Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</p>
</div>
</div>
</footer>
`;
exports[`<SiteFooter /> renders correctly does not render social links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="edX Home"
href="https://www.example.com"
>
<img
alt="edx Logo"
src="test-file-stub"
/>
</a>
<div
className="i18n d-flex mt-2"
>
<form
className="d-flex align-items-start"
onSubmit={[Function]}
>
<label
htmlFor="site-footer-language-select"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-language fa-w-20 fa-2x text-primary"
data-icon="language"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 640 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z"
fill="currentColor"
style={Object {}}
/>
</svg>
<div
className="sr-only"
>
Choose Language
</div>
</label>
<select
className="mx-2 mt-1"
defaultValue="en"
id="site-footer-language-select"
name="site-footer-language-select"
>
<option
value="en"
>
English
</option>
<option
value="es-419"
>
español
</option>
</select>
<button
className="mt-1"
type="submit"
>
Apply
</button>
</form>
</div>
</div>
<div
className="area-2"
>
<h2>
edX
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://business.edx.org/?utm_test=utm_test_value"
>
edX for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open edX
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5"
>
<li>
<a
href="https://store.apple.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from the Apple App Store"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a
href="https://play.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from Google Play"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
<p>
© 20122019 edX Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</p>
</div>
</div>
</footer>
`;
exports[`<SiteFooter /> renders correctly renders with social and mobile links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="edX Home"
href="https://www.example.com"
>
<img
alt="edx Logo"
src="test-file-stub"
/>
</a>
<div
className="i18n d-flex mt-2"
>
<form
className="d-flex align-items-start"
onSubmit={[Function]}
>
<label
htmlFor="site-footer-language-select"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-language fa-w-20 fa-2x text-primary"
data-icon="language"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 640 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z"
fill="currentColor"
style={Object {}}
/>
</svg>
<div
className="sr-only"
>
Choose Language
</div>
</label>
<select
className="mx-2 mt-1"
defaultValue="en"
id="site-footer-language-select"
name="site-footer-language-select"
>
<option
value="en"
>
English
</option>
<option
value="es-419"
>
español
</option>
</select>
<button
className="mt-1"
type="submit"
>
Apply
</button>
</form>
</div>
</div>
<div
className="area-2"
>
<h2>
edX
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
About
</a>
</li>
<li>
<a
href="https://business.edx.org/?utm_test=utm_test_value"
>
edX for Business
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
Affiliates
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
Open edX
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
Careers
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
News
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
Legal
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
Terms of Service & Honor Code
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
Privacy Policy
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
Accessibility Policy
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
Trademark Policy
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
Sitemap
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
Connect
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
Blog
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
Contact Us
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
Help Center
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
Media Kit
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
Donate
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4"
>
<li>
<a
href="https://www.facebook.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Facebook"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-facebook-square fa-w-14 fa-2x social-icon"
data-icon="facebook-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Like edX on Facebook
</span>
</a>
</li>
<li>
<a
href="https://www.twitter.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Twitter"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-twitter-square fa-w-14 fa-2x social-icon"
data-icon="twitter-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on Twitter
</span>
</a>
</li>
<li>
<a
href="https://www.youtube.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Youtube"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-youtube-square fa-w-14 fa-2x social-icon"
data-icon="youtube-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M186.8 202.1l95.2 54.1-95.2 54.1V202.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-42 176.3s0-59.6-7.6-88.2c-4.2-15.8-16.5-28.2-32.2-32.4C337.9 128 224 128 224 128s-113.9 0-142.2 7.7c-15.7 4.2-28 16.6-32.2 32.4-7.6 28.5-7.6 88.2-7.6 88.2s0 59.6 7.6 88.2c4.2 15.8 16.5 27.7 32.2 31.9C110.1 384 224 384 224 384s113.9 0 142.2-7.7c15.7-4.2 28-16.1 32.2-31.9 7.6-28.5 7.6-88.1 7.6-88.1z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX YouTube channel
</span>
</a>
</li>
<li>
<a
href="https://www.linkedin.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="LinkedIn"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-linkedin fa-w-14 fa-2x social-icon"
data-icon="linkedin"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Follow edX on LinkedIn
</span>
</a>
</li>
<li>
<a
href="https://reddit.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
title="Reddit"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-reddit-square fa-w-14 fa-2x social-icon"
data-icon="reddit-square"
data-prefix="fab"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"
fill="currentColor"
style={Object {}}
/>
</svg>
<span
className="sr-only"
>
Subscribe to the edX subreddit
</span>
</a>
</li>
</ul>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5"
>
<li>
<a
href="https://store.apple.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from the Apple App Store"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a
href="https://play.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the edX mobile app from Google Play"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
<p>
© 20122019 edX Inc.
<br />
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</p>
</div>
</div>
</footer>
`;

View File

@@ -1,265 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import qs from 'query-string';
const EVENT_NAMES = {
FOOTER_LINK: 'edx.bi.footer.link',
};
class SiteFooter extends React.Component {
constructor(props) {
super(props);
this.externalLinkClickHandler = this.externalLinkClickHandler.bind(this);
this.applyLanguageSelection = this.applyLanguageSelection.bind(this);
}
applyLanguageSelection(event) {
event.preventDefault();
const languageCode = event.target.elements['site-footer-language-select'].value;
const { languageForm: { onLanguageSelected } } = this.props;
onLanguageSelected(languageCode);
}
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);
}
formatUrl(linkData) {
const {
queryParams,
url,
} = linkData;
return queryParams ? `${url}/?${qs.stringify(queryParams)}` : url;
}
renderLinkList({ title, linkList }) {
if (linkList.length > 0) {
return (
<React.Fragment>
<h2>{title}</h2>
<ul className="list-unstyled p-0 m-0">
{linkList.map(link => (
<li key={link.url}>
<a href={this.formatUrl(link)}>{link.title}</a>
</li>
))}
</ul>
</React.Fragment>
);
}
return null;
}
renderMobileLinks() {
const {
showMobileLinks,
appleAppStore,
googlePlay,
} = this.props;
if (showMobileLinks) {
return (
<ul className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5">
<li>
<a href={appleAppStore.url} rel="noopener noreferrer" target="_blank" onClick={this.externalLinkClickHandler}>
<img
className="max-height-39"
alt={appleAppStore.altText}
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a href={googlePlay.url} rel="noopener noreferrer" target="_blank" onClick={this.externalLinkClickHandler}>
<img
className="max-height-39"
alt={googlePlay.altText}
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
);
}
return null;
}
render() {
const {
ariaLabel,
linkSectionOne,
linkSectionTwo,
linkSectionThree,
siteLogo,
socialLinks,
supportedLanguages,
languageForm,
marketingSiteBaseUrl,
copyright,
trademark,
} = this.props;
const showLanguageSelector = supportedLanguages.length > 0 &&
languageForm;
return (
<footer
role="contentinfo"
aria-label={ariaLabel}
className="footer d-flex justify-content-center border-top py-3 px-4"
>
<div className="max-width-1180 d-grid">
<div className="area-1">
<a
href={marketingSiteBaseUrl}
aria-label={siteLogo.ariaLabel}
>
<img src={siteLogo.src} alt={siteLogo.altText} />
</a>
{showLanguageSelector &&
<div className="i18n d-flex mt-2">
<form
className="d-flex align-items-start"
onSubmit={this.applyLanguageSelection}
>
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
<label htmlFor="site-footer-language-select">
{languageForm.icon}
<div className="sr-only">{languageForm.screenReaderLabel}</div>
</label>
<select
id="site-footer-language-select"
className="mx-2 mt-1"
name="site-footer-language-select"
defaultValue={languageForm.activeLanguage}
>
{supportedLanguages.map(({ value, label }) =>
<option key={value} value={value}>{label}</option>)}
</select>
<button className="mt-1" type="submit">{languageForm.submitLabel}</button>
</form>
</div>
}
</div>
<div className="area-2">{this.renderLinkList(linkSectionOne)}</div>
<div className="area-3">{this.renderLinkList(linkSectionTwo)}</div>
<div className="area-4">{this.renderLinkList(linkSectionThree)}</div>
<div className="area-5">
{socialLinks.length > 0 &&
<ul className="d-flex flex-row justify-content-between list-unstyled max-width-222 p-0 mb-4">
{socialLinks.map(link => (
<li key={link.url}>
<a
href={link.url}
title={link.title}
rel="noopener noreferrer"
target="_blank"
onClick={this.externalLinkClickHandler}
>
{link.icon}
<span className="sr-only">{link.screenReaderText}</span>
</a>
</li>
))}
</ul>
}
{this.renderMobileLinks()}
<p>
{copyright}
<br />
{trademark}
</p>
</div>
</div>
</footer>
);
}
}
const linkSectionShape = PropTypes.shape({
title: PropTypes.string,
linkList: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
queryParams: PropTypes.shape({}),
})),
});
SiteFooter.propTypes = {
ariaLabel: PropTypes.string.isRequired,
siteLogo: PropTypes.shape({
src: PropTypes.node,
altText: PropTypes.string,
ariaLabel: PropTypes.string,
}),
marketingSiteBaseUrl: PropTypes.string,
linkSectionOne: linkSectionShape,
linkSectionTwo: linkSectionShape,
linkSectionThree: linkSectionShape,
socialLinks: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
icon: PropTypes.element.isRequired,
screenReaderText: PropTypes.string.isRequired,
})),
showMobileLinks: PropTypes.bool,
appleAppStore: PropTypes.shape({
url: PropTypes.string,
altText: PropTypes.string,
}),
googlePlay: PropTypes.shape({
url: PropTypes.string,
altText: PropTypes.string,
}),
supportedLanguages: PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
})),
languageForm: PropTypes.shape({
screenReaderLabel: PropTypes.string.isRequired,
submitLabel: PropTypes.string.isRequired,
onLanguageSelected: PropTypes.func.isRequired,
icon: PropTypes.node.isRequired,
activeLanguage: PropTypes.string,
}),
copyright: PropTypes.oneOfType([
PropTypes.string,
PropTypes.node,
]),
trademark: PropTypes.oneOfType([
PropTypes.string,
PropTypes.node,
]),
handleAllTrackEvents: PropTypes.func.isRequired,
};
const linkSectionDefault = {
title: null,
linkList: [],
};
SiteFooter.defaultProps = {
siteLogo: null,
marketingSiteBaseUrl: null,
linkSectionOne: linkSectionDefault,
linkSectionTwo: linkSectionDefault,
linkSectionThree: linkSectionDefault,
socialLinks: [],
showMobileLinks: true,
appleAppStore: null,
googlePlay: null,
supportedLanguages: [],
languageForm: null,
copyright: null,
trademark: null,
};
export default SiteFooter;
export { EVENT_NAMES };

View File

@@ -1,3 +0,0 @@
import SiteFooter from './components/SiteFooter';
export default SiteFooter;

View File

@@ -1,165 +0,0 @@
.max-width-222 {
max-width: 222px;
}
.max-width-264 {
max-width: 264px;
}
.max-width-1180 {
max-width: 1180px;
}
.max-height-39 {
max-height: 39px;
}
.d-grid {
display: grid;
}
$gray-footer: #fcfcfc;
$border-1: 1px solid $gray-200;
.footer {
background-color: $gray-footer;
.area-1 {
grid-column: 1;
grid-row: 1;
border-bottom: $border-1;
padding-bottom: 1rem;
}
.area-2 {
grid-column: 1;
grid-row: 2;
border-bottom: $border-1;
padding: 1rem 0;
}
.area-3 {
grid-column: 1;
grid-row: 3;
border-bottom: $border-1;
padding: 1rem 0;
}
.area-4 {
grid-column: 1;
grid-row: 4;
border-bottom: $border-1;
padding: 1rem 0;
}
.area-5 {
grid-column: 1;
grid-row: 5;
padding: 1rem 0;
}
@media only screen and (min-width: 717px) {
.area-1 {
grid-column: 1 / span 2;
grid-row: 1;
border-bottom: none;
padding: 1rem 0;
}
.area-2 {
grid-column: 1;
grid-row: 2;
}
.area-3 {
grid-column: 1;
grid-row: 3;
}
.area-4 {
grid-column: 1;
grid-row: 4;
border-bottom: none;
}
.area-5 {
grid-column: 2;
grid-row: 2 / span 3;
border-left: $border-1;
padding-left: 1rem;
margin-left: 1rem;
}
}
@media only screen and (min-width: 870px) {
.area-1 {
grid-column: 1;
grid-row: 1 / span 3;
border-right: $border-1;
padding-right: 1rem;
margin-right: 1rem;
}
.area-2 {
grid-column: 2;
grid-row: 1;
border-bottom: none;
border-right: $border-1;
padding-right: 1rem;
margin-right: 1rem;
}
.area-3 {
grid-column: 3;
grid-row: 1;
border-bottom: none;
border-right: $border-1;
padding-right: 1rem;
margin-right: 1rem;
}
.area-4 {
grid-column: 4;
grid-row: 1;
}
.area-5 {
grid-column: 2 / span 3;
grid-row: 2;
border: none;
margin-left: 0;
padding-left: 0;
}
}
@media only screen and (min-width: 1188px) {
.area-1 {
grid-column: 1 / span 1;
grid-row: 1;
}
.area-2 {
grid-column: 2;
grid-row: 1;
}
.area-3 {
grid-column: 3;
grid-row: 1;
}
.area-4 {
grid-column: 4;
grid-row: 1;
border-right: $border-1;
padding-right: 1rem;
margin-right: 1rem;
}
.area-5 {
grid-column: 5 / span 1;
grid-row: 1;
max-width: 372px;
}
}
}

26
src/setupTest.js Normal file
View File

@@ -0,0 +1,26 @@
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
// These configuration values are usually set in webpack's EnvironmentPlugin however
// Jest does not use webpack so we need to set these so for testing
process.env.ACCESS_TOKEN_COOKIE_NAME = 'edx-jwt-cookie-header-payload';
process.env.BASE_URL = 'localhost:1995';
process.env.CREDENTIALS_BASE_URL = 'http://localhost:18150';
process.env.CSRF_TOKEN_API_PATH = '/csrf/api/v1/token';
process.env.ECOMMERCE_BASE_URL = 'http://localhost:18130';
process.env.LANGUAGE_PREFERENCE_COOKIE_NAME = 'openedx-language-preference';
process.env.LMS_BASE_URL = 'http://localhost:18000';
process.env.LOGIN_URL = 'http://localhost:18000/login';
process.env.LOGOUT_URL = 'http://localhost:18000/login';
process.env.MARKETING_SITE_BASE_URL = 'http://localhost:18000';
process.env.ORDER_HISTORY_URL = 'localhost:1996/orders';
process.env.REFRESH_ACCESS_TOKEN_ENDPOINT = 'http://localhost:18000/login_refresh';
process.env.SEGMENT_KEY = 'segment_whoa';
process.env.SITE_NAME = 'edX';
process.env.USER_INFO_COOKIE_NAME = 'edx-user-info';
process.env.LOGO_URL = 'https://edx-cdn.org/v3/default/logo.svg';
process.env.LOGO_TRADEMARK_URL = 'https://edx-cdn.org/v3/default/logo-trademark.svg';
process.env.LOGO_WHITE_URL = 'https://edx-cdn.org/v3/default/logo-white.svg';
process.env.FAVICON_URL = 'https://edx-cdn.org/v3/default/favicon.ico';

View File

@@ -1,4 +0,0 @@
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });

1275
stats.json

File diff suppressed because one or more lines are too long

15
webpack.dev.config.js Normal file
View File

@@ -0,0 +1,15 @@
const path = require('path');
const { createConfig } = require('@edx/frontend-build');
module.exports = createConfig('webpack-dev', {
entry: path.resolve(__dirname, 'example'),
output: {
path: path.resolve(__dirname, 'example/dist'),
publicPath: '/',
},
resolve: {
alias: {
'@edx/frontend-component-footer': path.resolve(__dirname, 'src'),
},
},
});