@financial-times/n-myft-ui 23.1.2 → 24.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import FollowButton from '../../components/follow-button/follow-button';
3
+
4
+ export default function Demo (props) {
5
+
6
+ const {
7
+ title,
8
+ flags,
9
+ followButton,
10
+ } = props;
11
+
12
+ const followButtonProps = {...followButton, flags};
13
+
14
+ return (
15
+ <div className="o-grid-container o-grid-container--snappy demo-container">
16
+ <h1>{title}</h1>
17
+
18
+ <section
19
+ id="follow-button"
20
+ className="demo-section">
21
+ <div className="o-grid-row">
22
+ <div data-o-grid-colspan="12">
23
+ <h2
24
+ className="demo-section__title">
25
+ Follow button
26
+ </h2>
27
+ <FollowButton {...followButtonProps} />
28
+ </div>
29
+ </div>
30
+ </section>
31
+ </div>
32
+ )
33
+ }
package/jest.config.js ADDED
@@ -0,0 +1,8 @@
1
+ module.exports = {
2
+ transform: {
3
+ '.(js|jsx)': '@sucrase/jest-plugin',
4
+ },
5
+ testEnvironment: 'jest-environment-jsdom',
6
+ modulePathIgnorePatterns: ['node_modules', 'bower_components'],
7
+ testMatch: ['<rootDir>/components/**/*.test.js']
8
+ };
@@ -4,28 +4,32 @@ $myft-lozenge-themes: (
4
4
  text: oColorsByName('white'),
5
5
  highlight: oColorsByName('claret-50'),
6
6
  pressed-highlight: rgba(oColorsByName('black'), 0.05),
7
- disabled: rgba(oColorsByName('black'), 0.5)
7
+ disabled: rgba(oColorsByName('black'), 0.5),
8
+ focus-outline: oColorsByUsecase('focus', 'outline', $fallback: null)
8
9
  ),
9
10
  inverse: (
10
11
  background: oColorsByName('white'),
11
12
  text: oColorsByName('claret'),
12
13
  highlight: rgba(white, 0.8),
13
14
  pressed-highlight: rgba(white, 0.2),
14
- disabled: rgba(oColorsByName('white'), 0.5)
15
+ disabled: rgba(oColorsByName('white'), 0.5),
16
+ focus-outline: oColorsByName('white')
15
17
  ),
16
18
  opinion: (
17
19
  background: oColorsByName('oxford-40'),
18
20
  text: oColorsByName('white'),
19
21
  highlight: oColorsByName('oxford-30'),
20
22
  pressed-highlight: rgba(oColorsByName('oxford-40'), 0.2),
21
- disabled: rgba(oColorsByName('black'), 0.5)
23
+ disabled: rgba(oColorsByName('black'), 0.5),
24
+ focus-outline: oColorsByUsecase('focus', 'outline', $fallback: null)
22
25
  ),
23
26
  monochrome: (
24
27
  background: oColorsByName('white'),
25
28
  text: oColorsByName('black'),
26
29
  highlight: oColorsByName('white-80'),
27
30
  pressed-highlight: rgba(oColorsByName('white'), 0.2),
28
- disabled: rgba(oColorsByName('white'), 0.5)
31
+ disabled: rgba(oColorsByName('white'), 0.5),
32
+ focus-outline: oColorsByName('white')
29
33
  )
30
34
  );
31
35
 
@@ -1,6 +1,54 @@
1
1
  @import './themes';
2
2
  @import './toggle-icon';
3
3
 
4
+ @mixin focusOutlineColor($focus-color) {
5
+ // Apply :focus styles as a fallback
6
+ // These styles will be applied to all browsers that don't use the polyfill, this includes browsers which support the feature natively.
7
+ body:not(.js-focus-visible) &,
8
+ html:not(.js-focus-visible) & {
9
+ // Standardise focus styles.
10
+ &:focus {
11
+ outline: 2px solid $focus-color;
12
+ }
13
+ }
14
+
15
+ // When the focus-visible polyfill is applied `.js-focus-visible` is added to the html dom node
16
+ // (the body node in v4 of the 3rd party polyfill)
17
+
18
+ // stylelint-disable-next-line selector-no-qualifying-type
19
+ body.js-focus-visible &, // stylelint-disable-next-line selector-no-qualifying-type
20
+ html.js-focus-visible & {
21
+ // Standardise focus styles.
22
+ // stylelint-disable-next-line selector-no-qualifying-type
23
+ &.focus-visible {
24
+ outline: 2px solid $focus-color;
25
+ }
26
+ // Disable browser default focus style.
27
+ // stylelint-disable-next-line selector-no-qualifying-type
28
+ &:focus:not(.focus-visible) {
29
+ outline: 0;
30
+ }
31
+ }
32
+
33
+ // These styles will be ignored by browsers which do not recognise the :focus-visible selector (as per the third bullet point in https://www.w3.org/TR/selectors-3/#Conformance)
34
+ // If a browser supports :focus-visible we unset the :focus styles that were applied above
35
+ // (within the html:not(.js-focus-visible) block).
36
+ &:focus-visible,
37
+ body:not(.js-focus-visible) &:focus,
38
+ html:not(.js-focus-visible) &:focus {
39
+ outline: unset;
40
+ }
41
+
42
+ // Styles given :focus-visible support. Extra selectors needed to match
43
+ // previous `:focus` selector specificity.
44
+ body:not(.js-focus-visible) &:focus-visible,
45
+ html:not(.js-focus-visible) &:focus-visible,
46
+ &:focus-visible {
47
+ outline: 2px solid $focus-color;
48
+ }
49
+ }
50
+
51
+
4
52
  @mixin myftLozengeTheme($theme: standard, $with-toggle-icon: false) {
5
53
  @if $with-toggle-icon != false {
6
54
  @include myftToggleIcon($theme);
@@ -11,6 +59,8 @@
11
59
  border: 1px solid getThemeColor(background);
12
60
  color: getThemeColor(background);
13
61
 
62
+ @include focusOutlineColor(getThemeColor(focus-outline));
63
+
14
64
  &:hover,
15
65
  &:focus {
16
66
  background-color: getThemeColor(pressed-highlight);
@@ -57,8 +107,4 @@
57
107
  text-overflow: ellipsis;
58
108
  transition: border-color, background-color 0.5s ease;
59
109
  white-space: nowrap;
60
-
61
- &:focus {
62
- outline: 2px solid oColorsByName('teal-90');
63
- }
64
110
  }
package/package.json CHANGED
@@ -1,15 +1,13 @@
1
1
  {
2
2
  "name": "@financial-times/n-myft-ui",
3
- "version": "23.1.2",
3
+ "version": "24.0.2",
4
4
  "description": "Client side component for interaction with myft",
5
5
  "main": "server.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1",
8
8
  "commit": "commit-wizard",
9
- "precommit": "node_modules/.bin/secret-squirrel",
10
- "prepush": "make verify -j3",
11
- "commitmsg": "node_modules/.bin/secret-squirrel-commitmsg",
12
- "prepare": "npx snyk protect || npx snyk protect -d || true"
9
+ "prepare": "npx snyk protect || npx snyk protect -d || true",
10
+ "preinstall": "npm_config_yes=true npx check-engine"
13
11
  },
14
12
  "repository": {
15
13
  "type": "git",
@@ -27,10 +25,13 @@
27
25
  "@financial-times/dotcom-build-js": "0.4.1",
28
26
  "@financial-times/dotcom-build-sass": "0.4.1",
29
27
  "@financial-times/dotcom-page-kit-cli": "0.4.1",
30
- "@financial-times/n-gage": "^3.12.0",
31
- "@financial-times/n-heroku-tools": "8.3.1",
32
- "@financial-times/n-internal-tool": "2.3.4",
33
- "@financial-times/x-handlebars": "1.0.0-beta.21",
28
+ "@financial-times/dotcom-server-handlebars": "^3.0.0",
29
+ "@financial-times/dotcom-server-react-jsx": "^2.6.2",
30
+ "@financial-times/n-express": "^22.4.1",
31
+ "@financial-times/n-gage": "^8.3.2",
32
+ "@sucrase/jest-plugin": "^2.2.0",
33
+ "@testing-library/jest-dom": "^5.16.1",
34
+ "@testing-library/react": "^12.1.2",
34
35
  "ascii-table": "0.0.9",
35
36
  "autoprefixer": "9.7.0",
36
37
  "aws-sdk-mock": "4.5.0",
@@ -50,9 +51,11 @@
50
51
  "brotli": "^1.3.1",
51
52
  "chai": "4.2.0",
52
53
  "chalk": "2.4.2",
54
+ "check-engine": "^1.10.1",
53
55
  "css-loader": "^0.23.1",
54
56
  "denodeify": "^1.2.1",
55
57
  "eslint": "6.5.1",
58
+ "eslint-plugin-react": "^7.27.1",
56
59
  "extract-css-block-webpack-plugin": "^1.3.0",
57
60
  "extract-text-webpack-plugin": "3.0.2",
58
61
  "fetch-mock": "^5.0.3",
@@ -62,6 +65,8 @@
62
65
  "hyperons": "^0.4.1",
63
66
  "imports-loader": "0.8.0",
64
67
  "inject-loader": "^3.0.0",
68
+ "jest": "^27.4.5",
69
+ "jsdom": "^19.0.0",
65
70
  "karma": "4.4.1",
66
71
  "karma-browserstack-launcher": "1.5.1",
67
72
  "karma-chai": "^0.1.0",
@@ -78,21 +83,37 @@
78
83
  "mocha": "6.2.2",
79
84
  "mockery": "2.1.0",
80
85
  "node-fetch": "2.6.0",
81
- "node-sass": "4.13.0",
86
+ "node-sass": "^4.14.1",
82
87
  "nodemon": "^1.9.2",
83
88
  "npm-prepublish": "^1.2.1",
84
89
  "pa11y-ci": "^2.1.1",
85
90
  "postcss-loader": "^0.9.1",
91
+ "react": "^17.0.2",
86
92
  "regenerator-runtime": "^0.13.3",
87
- "sass-loader": "^3.2.0",
88
93
  "semver": "6.3.0",
89
94
  "sinon": "^7.1.0",
90
95
  "sinon-chai": "^3.2.0",
91
- "snyk": "^1.216.5"
96
+ "snyk": "^1.216.5",
97
+ "sucrase": "^3.10.1"
98
+ },
99
+ "volta": {
100
+ "node": "12.22.5",
101
+ "npm": "7.20.2"
102
+ },
103
+ "engines": {
104
+ "node": "12.x",
105
+ "npm": "7.x || 8.x"
92
106
  },
93
107
  "x-dash": {
94
108
  "engine": {
95
109
  "server": "hyperons"
96
110
  }
111
+ },
112
+ "husky": {
113
+ "hooks": {
114
+ "commit-msg": "node_modules/.bin/secret-squirrel-commitmsg",
115
+ "pre-commit": "node_modules/.bin/secret-squirrel",
116
+ "pre-push": "make verify -j3"
117
+ }
97
118
  }
98
119
  }
@@ -1,5 +0,0 @@
1
- <input
2
- data-myft-csrf-token
3
- value="{{#if @root.cacheablePersonalisedUrl}}{{@root.csrfToken}}{{/if}}"
4
- type="hidden"
5
- name="token">
@@ -1,79 +0,0 @@
1
- {{#if @root.flags.myFtApiWrite}}
2
- <form
3
- class="n-myft-ui n-myft-ui--follow {{extraClasses}}"
4
- method="GET"
5
- data-myft-ui="follow"
6
- data-concept-id="{{conceptId}}"
7
- {{#if collectionName}}data-myft-tracking="collectionName={{collectionName}}"{{/if}}
8
- {{#if followPlusDigestEmail}}
9
- action="/__myft/api/core/follow-plus-digest-email/{{conceptId}}?method=put"
10
- data-myft-ui-variant="followPlusDigestEmail"
11
- {{else}}
12
- {{#ifAll setFollowButtonStateToSelected @root.cacheablePersonalisedUrl}}
13
- action="/myft/remove/{{conceptId}}"
14
- data-js-action="/__myft/api/core/followed/concept/{{conceptId}}?method=delete"
15
- {{else}}
16
- action="/myft/add/{{conceptId}}"
17
- data-js-action="/__myft/api/core/followed/concept/{{conceptId}}?method=put"
18
- {{/ifAll}}
19
- {{/if}}>
20
- {{> n-myft-ui/components/csrf-token/input}}
21
- <div
22
- class="n-myft-ui__announcement o-normalise-visually-hidden"
23
- aria-live="assertive"
24
- data-pressed-text="Now following {{name}}."
25
- data-unpressed-text="No longer following {{name}}."
26
- ></div>
27
- <button
28
- {{#ifAll setFollowButtonStateToSelected @root.cacheablePersonalisedUrl}}
29
- aria-label="Remove {{name}} from myFT"
30
- title="Remove {{name}} from myFT"
31
- data-alternate-label="Add {{name}} to myFT"
32
- aria-pressed="true"
33
- {{#if alternateText}}
34
- data-alternate-text="{{alternateText}}"
35
- {{else}}
36
- {{#if buttonText}}
37
- data-alternate-text="{{buttonText}}"
38
- {{else}}
39
- data-alternate-text="Add to myFT"
40
- {{/if}}
41
- {{/if}}
42
- {{else}}
43
- aria-pressed="false"
44
- aria-label="Add {{name}} to myFT"
45
- title="Add {{name}} to myFT"
46
- data-alternate-label="Remove {{name}} from myFT"
47
- {{#if alternateText}}
48
- data-alternate-text="{{alternateText}}"
49
- {{else}}
50
- {{#if buttonText}}
51
- data-alternate-text="{{buttonText}}"
52
- {{else}}
53
- data-alternate-text="Added"
54
- {{/if}}
55
- {{/if}}
56
- {{/ifAll}}
57
- class="{{extraButtonClasses}}
58
- n-myft-follow-button
59
- {{~#variant}} n-myft-follow-button--{{this}}{{/variant~}}"
60
- data-concept-id="{{conceptId}}" {{! duplicated here for tracking}}
61
- {{#if followPlusDigestEmail}}
62
- data-trackable-context-messaging="add-to-myft-plus-digest-button"
63
- {{/if}}
64
- data-trackable="follow"
65
- type="submit">
66
- {{~#if buttonText~}}
67
- {{buttonText}}
68
- {{~else~}}
69
- {{~#ifAll setFollowButtonStateToSelected @root.cacheablePersonalisedUrl~}}
70
- Added
71
- {{~else~}}
72
- Add to myFT
73
- {{~/ifAll~}}
74
- {{~/if~}}
75
- </button>
76
- </form>
77
- {{else}}
78
- <!-- Add to myFT button hidden due to myFtApiWrite being off -->
79
- {{/if}}
@@ -1,6 +0,0 @@
1
- {
2
- "conceptId": "00000000-0000-0000-0000-000000000044",
3
- "name": "Keith inc.",
4
- "directType": "http://www.ft.com/ontology/company/PublicCompany",
5
- "followPlusDigestEmail": true
6
- }
@@ -1,12 +0,0 @@
1
- <div class="o-grid-container o-grid-container--snappy">
2
- <h1>{{title}}</h1>
3
- <div class="o-grid-row">
4
- <div data-o-grid-colspan="12">
5
- <h2>Follow button</h2>
6
-
7
- {{#followButton}}
8
- {{> n-myft-ui/components/follow-button/follow-button}}
9
- {{/followButton}}
10
- </div>
11
- </div>
12
- </div>