@financial-times/n-myft-ui 30.4.0 → 30.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,6 +11,7 @@
11
11
  border-radius: 10px;
12
12
  border: 2px solid oColorsByName('black-5');
13
13
  width: 275px;
14
+ text-transform: none;
14
15
  z-index: 9999999;
15
16
  }
16
17
 
@@ -0,0 +1,40 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = CsrfToken;
7
+
8
+ var _react = require('react');
9
+
10
+ var _react2 = _interopRequireDefault(_react);
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ /**
15
+ * @typedef {object} CsrfInputProperties
16
+ * @property {string} [csrfToken]
17
+ * A token to mitigate Cross Site Request Forgery
18
+ * @property {boolean} [cacheablePersonalisedUrl]
19
+ * An indicator to decide whether its safe to set the button state on the server side. eg. there is no cache or the cache is personalised
20
+ */
21
+
22
+ /**
23
+ * Create a follow plus instant alerts button component
24
+ * @public
25
+ * @param {CsrfInputProperties}
26
+ * @returns {React.ReactElement}
27
+ */
28
+
29
+ function CsrfToken(_ref) {
30
+ var csrfToken = _ref.csrfToken,
31
+ cacheablePersonalisedUrl = _ref.cacheablePersonalisedUrl;
32
+
33
+
34
+ var token = cacheablePersonalisedUrl ? csrfToken : '';
35
+ return _react2.default.createElement('input', {
36
+ 'data-myft-csrf-token': true,
37
+ value: token,
38
+ type: 'hidden',
39
+ name: 'token' });
40
+ }
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8
+
9
+ exports.default = FollowPlusInstantAlerts;
10
+
11
+ var _react = require('react');
12
+
13
+ var _react2 = _interopRequireDefault(_react);
14
+
15
+ var _input = require('../csrf-token/input');
16
+
17
+ var _input2 = _interopRequireDefault(_input);
18
+
19
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
+
21
+ /**
22
+ * @typedef {object} FollowProperties
23
+ * @property {string} conceptId
24
+ * The ID for the concept
25
+ * @property {string} name
26
+ * The user facing label for the concept
27
+ * @property {string} [csrfToken]
28
+ * A token to mitigate Cross Site Request Forgery
29
+ * @property {boolean} [setFollowButtonStateToSelected]
30
+ * An indicator to state whether the button state should be set to selected on the server side
31
+ * @property {boolean} [cacheablePersonalisedUrl]
32
+ * An indicator to decide whether its safe to set the button state on the server side. eg. there is no cache or the cache is personalised
33
+ * @property {boolean} [setInstantAlertsOn]
34
+ * An indicator to switch the rendering to show instant alerts as turned on
35
+ * @property {object.<string, boolean>} flags
36
+ * FT.com feature flags
37
+ * @property {string} variant
38
+ * color variant of the follow button
39
+ */
40
+
41
+ /**
42
+ * Create a follow plus instant alerts button component
43
+ * @public
44
+ * @param {FollowProperties}
45
+ * @returns {React.ReactElement}
46
+ */
47
+
48
+ function FollowPlusInstantAlerts(_ref) {
49
+ var conceptId = _ref.conceptId,
50
+ name = _ref.name,
51
+ csrfToken = _ref.csrfToken,
52
+ setFollowButtonStateToSelected = _ref.setFollowButtonStateToSelected,
53
+ cacheablePersonalisedUrl = _ref.cacheablePersonalisedUrl,
54
+ setInstantAlertsOn = _ref.setInstantAlertsOn,
55
+ flags = _ref.flags,
56
+ variant = _ref.variant;
57
+
58
+ if (!flags.myFtApiWrite) {
59
+ return null;
60
+ }
61
+
62
+ var dynamicFormAttributes = setFollowButtonStateToSelected && cacheablePersonalisedUrl ? {
63
+ 'action': '/myft/remove/' + conceptId,
64
+ 'data-js-action': '/__myft/api/core/followed/concept/' + conceptId + '?method=delete'
65
+ } : {
66
+ 'action': '/myft/add/' + conceptId,
67
+ 'data-js-action': '/__myft/api/core/followed/concept/' + conceptId + '?method=put'
68
+ };
69
+
70
+ var dynamicButtonAttributes = setFollowButtonStateToSelected && cacheablePersonalisedUrl ? {
71
+ 'aria-label': 'Added ' + name + ' to myFT: click to manage alert preferences or remove from myFT',
72
+ 'title': 'Manage ' + name + ' alert preferences or remove from myFT',
73
+ 'data-alternate-label': 'Add to myFT: ' + name,
74
+ 'aria-pressed': true,
75
+ 'data-alternate-text': 'Add to myFT'
76
+ } : {
77
+ 'aria-label': 'Add ' + name + ' to myFT',
78
+ 'title': 'Add ' + name + ' to myFT',
79
+ 'data-alternate-label': 'Added ' + name + ' to myFT: click to manage alert preferences or remove from myFT',
80
+ 'aria-pressed': false,
81
+ 'data-alternate-text': 'Added'
82
+ };
83
+
84
+ var buttonText = setFollowButtonStateToSelected && cacheablePersonalisedUrl ? 'Added' : 'Add to myFT';
85
+
86
+ return _react2.default.createElement(
87
+ 'form',
88
+ _extends({}, dynamicFormAttributes, {
89
+ className: 'n-myft-ui n-myft-ui--follow',
90
+ method: 'GET',
91
+ 'data-myft-ui': 'follow',
92
+ 'data-concept-id': conceptId,
93
+ 'data-myft-ui-variant': 'followPlusInstantAlerts' }),
94
+ _react2.default.createElement('div', {
95
+ className: 'n-myft-ui__announcement o-normalise-visually-hidden',
96
+ 'aria-live': 'assertive',
97
+ 'data-pressed-text': 'Now following ' + name + '.',
98
+ 'data-unpressed-text': 'No longer following ' + name + '.'
99
+ }),
100
+ _react2.default.createElement(_input2.default, {
101
+ cacheablePersonalisedUrl: cacheablePersonalisedUrl,
102
+ csrfToken: csrfToken
103
+ }),
104
+ _react2.default.createElement(
105
+ 'button',
106
+ _extends({}, dynamicButtonAttributes, {
107
+ className: 'n-myft-follow-button n-myft-follow-button--instant-alerts\n\t\t\t\t\t\t' + (setInstantAlertsOn ? 'n-myft-follow-button--instant-alerts--on' : '') + '\n\t\t\t\t\t\t' + (variant ? 'n-myft-follow-button--' + variant : ''),
108
+ 'data-concept-id': conceptId,
109
+ 'data-trackable': 'follow',
110
+ type: 'submit',
111
+ 'data-component-id': 'myft-follow-plus-instant-alerts' }),
112
+ buttonText
113
+ )
114
+ );
115
+ };
@@ -0,0 +1,83 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = InstantAlertsPreferencesModal;
7
+
8
+ var _react = require('react');
9
+
10
+ var _react2 = _interopRequireDefault(_react);
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ /**
15
+ * @typedef {Object} PreferencesProperties
16
+ * @property {string} conceptId
17
+ * Concept id of the concept which the modal controls
18
+ * @property {Record<string, boolean>} flags
19
+ * FT.com feature flags
20
+ * @property {boolean} visible
21
+ * Controls the visibility of the modal
22
+ */
23
+
24
+ /**
25
+ * Create a popup modal to manage myFT alert preferences
26
+ * @public
27
+ * @param {PreferencesProperties}
28
+ * @returns {React.ReactElement}
29
+ */
30
+ function InstantAlertsPreferencesModal(_ref) {
31
+ var flags = _ref.flags,
32
+ conceptId = _ref.conceptId,
33
+ visible = _ref.visible;
34
+
35
+ if (!flags.myFtApiWrite) {
36
+ return null;
37
+ }
38
+
39
+ return _react2.default.createElement(
40
+ 'div',
41
+ {
42
+ className: 'n-myft-ui__preferences-modal ' + (visible ? 'n-myft-ui__preferences-modal--show' : ''),
43
+ 'data-component-id': 'myft-preferences-modal',
44
+ 'data-concept-id': conceptId
45
+ },
46
+ _react2.default.createElement(
47
+ 'div',
48
+ { className: 'n-myft-ui__preferences-modal__content' },
49
+ _react2.default.createElement(
50
+ 'span',
51
+ { className: 'o-forms-input o-forms-input--checkbox' },
52
+ _react2.default.createElement(
53
+ 'label',
54
+ { htmlFor: 'receive-instant-alerts' },
55
+ _react2.default.createElement('input', {
56
+ id: 'receive-instant-alerts',
57
+ type: 'checkbox',
58
+ name: 'receive-instant-alerts',
59
+ value: 'receive-instant-alerts',
60
+ 'data-component-id': 'myft-preferences-modal-checkbox'
61
+ }),
62
+ _react2.default.createElement(
63
+ 'span',
64
+ { className: 'o-forms-input__label n-myft-ui__preferences-modal__checkbox__message' },
65
+ 'Get instant alerts for this topic'
66
+ )
67
+ )
68
+ ),
69
+ _react2.default.createElement('p', { 'data-component-id': 'myft-preferences-modal-list', className: 'n-myft-ui__preferences-modal__text' }),
70
+ _react2.default.createElement(
71
+ 'a',
72
+ { className: 'n-myft-ui__preferences-modal__text', href: '/myft/alerts' },
73
+ 'Manage your preferences here'
74
+ ),
75
+ _react2.default.createElement('span', { className: 'n-myft-ui__preferences-modal-error', 'data-component-id': 'myft-preference-modal-error' }),
76
+ _react2.default.createElement(
77
+ 'button',
78
+ { className: 'n-myft-ui__preferences-modal__remove-button', 'data-component-id': 'myft-preference-modal-remove' },
79
+ 'Remove from myFT'
80
+ )
81
+ )
82
+ );
83
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/n-myft-ui",
3
- "version": "30.4.0",
3
+ "version": "30.4.3",
4
4
  "description": "Client side component for interaction with myft",
5
5
  "main": "server.js",
6
6
  "scripts": {
@@ -30,6 +30,7 @@
30
30
  "ascii-table": "0.0.9",
31
31
  "autoprefixer": "9.7.0",
32
32
  "aws-sdk-mock": "4.5.0",
33
+ "babel-cli": "^6.26.0",
33
34
  "babel-core": "^6.2.1",
34
35
  "babel-loader": "7.1.4",
35
36
  "babel-plugin-add-module-exports": "^0.3.0",
@@ -39,6 +40,7 @@
39
40
  "babel-plugin-transform-runtime": "^6.23.0",
40
41
  "babel-preset-env": "^1.7.0",
41
42
  "babel-preset-es2015": "^6.6.0",
43
+ "babel-preset-react": "^6.24.1",
42
44
  "babel-runtime": "^6.9.2",
43
45
  "brotli": "^1.3.1",
44
46
  "chai": "4.2.0",