@financial-times/n-myft-ui 25.0.1 → 26.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.circleci/config.yml +3 -0
- package/README.md +50 -0
- package/build-state/npm-shrinkwrap.json +14847 -15637
- package/components/collections/collections.jsx +68 -0
- package/components/collections/collections.test.js +83 -0
- package/components/concept-list/concept-list.jsx +69 -0
- package/components/concept-list/concept-list.test.js +116 -0
- package/components/csrf-token/input.jsx +1 -7
- package/components/csrf-token/{__tests__/input.test.js → input.test.js} +2 -2
- package/components/follow-button/follow-button.jsx +6 -4
- package/components/follow-button/{__tests__/follow-button.test.js → follow-button.test.js} +4 -4
- package/components/index.js +17 -0
- package/components/instant-alert/instant-alert.jsx +73 -0
- package/components/instant-alert/instant-alert.test.js +86 -0
- package/components/pin-button/pin-button.jsx +40 -0
- package/components/pin-button/pin-button.test.js +57 -0
- package/components/save-for-later/save-for-later.jsx +101 -0
- package/components/save-for-later/save-for-later.test.js +59 -0
- package/demos/app.js +2 -4
- package/demos/templates/demo.html +8 -9
- package/demos/templates/demo.jsx +93 -1
- package/dist/bundles/bundle.js +3232 -0
- package/jsx-migration.md +16 -0
- package/package.json +7 -3
- package/webpack.config.js +34 -0
- package/components/collections/collections.html +0 -77
- package/components/concept-list/concept-list.html +0 -28
- package/components/instant-alert/instant-alert.html +0 -47
- package/components/pin-button/pin-button.html +0 -20
- package/components/save-for-later/save-for-later.html +0 -67
package/jsx-migration.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
### Handlebars to JSX migration notes
|
2
|
+
|
3
|
+
This document serves as a troubleshooting guide for `handlebars` components that have been migrated to `jsx`. Also, notes can be added to this document for anything related to the migration.
|
4
|
+
|
5
|
+
A common cause of issues/bugs with migrated components is missing HTML attributes. The business logic related to these components heavily depend on these attributes and their values. If an action related to any of these migrated components fails, compare the jsx version and the handlebars version to see if an attribute is getting the wrong value or is missing.
|
6
|
+
|
7
|
+
Another cause of issues will be missing flags. Ensure consuming applications pass the required flags to these components.
|
8
|
+
|
9
|
+
Currently we have migrated the following `handlebars` partials to `jsx`:
|
10
|
+
- components/collections/collections.jsx [handlebars fount here](https://github.com/Financial-Times/n-myft-ui/blob/dfbf06d10f78756871cfe8d2aeb863ce4bcca1e1/components/collections/collections.html)
|
11
|
+
- components/concept-list/concept-list.jsx [handlebars found here](https://github.com/Financial-Times/n-myft-ui/blob/dfbf06d10f78756871cfe8d2aeb863ce4bcca1e1/components/concept-list/concept-list.html)
|
12
|
+
- components/follow-button/follow-button.jsx [handlebars found here](https://github.com/Financial-Times/n-myft-ui/blob/bf2145fcfd211001dfab6a3a271dd72808d062bd/components/follow-button/follow-button.html)
|
13
|
+
- components/pin-button/pin-button.jsx [handlebars found here](https://github.com/Financial-Times/n-myft-ui/blob/dfbf06d10f78756871cfe8d2aeb863ce4bcca1e1/components/pin-button/pin-button.html)
|
14
|
+
- components/save-for-later/save-for-later.jsx [handlebars found here](https://github.com/Financial-Times/n-myft-ui/blob/11d483364bb0f002c3a0b45bc024c83bb055268e/components/save-for-later/save-for-later.jsx)
|
15
|
+
- components/instant-alert/instant-alert.jsx [handlebars found here](https://github.com/Financial-Times/n-myft-ui/blob/dfbf06d10f78756871cfe8d2aeb863ce4bcca1e1/components/instant-alert/instant-alert.html)
|
16
|
+
- components/csrf-token/input.jsx [handlebars found here](https://github.com/Financial-Times/n-myft-ui/blob/bf2145fcfd211001dfab6a3a271dd72808d062bd/components/csrf-token/input.html)
|
package/package.json
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
{
|
2
2
|
"name": "@financial-times/n-myft-ui",
|
3
|
-
"version": "
|
3
|
+
"version": "26.0.0",
|
4
4
|
"description": "Client side component for interaction with myft",
|
5
|
-
"main": "
|
5
|
+
"main": "dist/bundles/bundle.js",
|
6
|
+
"module": "dist/bundles/bundle.js",
|
6
7
|
"scripts": {
|
7
8
|
"test": "echo \"Error: no test specified\" && exit 1",
|
8
9
|
"commit": "commit-wizard",
|
9
10
|
"prepare": "npx snyk protect || npx snyk protect -d || true",
|
10
|
-
"preinstall": "[ \"$INIT_CWD\" != \"$PWD\" ] || npm_config_yes=true npx check-engine"
|
11
|
+
"preinstall": "[ \"$INIT_CWD\" != \"$PWD\" ] || npm_config_yes=true npx check-engine",
|
12
|
+
"build-package": "webpack"
|
11
13
|
},
|
12
14
|
"repository": {
|
13
15
|
"type": "git",
|
@@ -44,6 +46,8 @@
|
|
44
46
|
"babel-plugin-transform-runtime": "^6.9.0",
|
45
47
|
"babel-preset-env": "^1.7.0",
|
46
48
|
"babel-preset-es2015": "^6.6.0",
|
49
|
+
"babel-preset-react": "^6.24.1",
|
50
|
+
"babel-preset-stage-2": "^6.24.1",
|
47
51
|
"babel-runtime": "^6.9.2",
|
48
52
|
"bower": "^1.8.8",
|
49
53
|
"bower-resolve-webpack-plugin": "^1.0.5",
|
@@ -0,0 +1,34 @@
|
|
1
|
+
const path = require('path');
|
2
|
+
|
3
|
+
module.exports = {
|
4
|
+
entry: './components/index.js',
|
5
|
+
resolve: {
|
6
|
+
extensions: ['.js', '.jsx']
|
7
|
+
},
|
8
|
+
module: {
|
9
|
+
rules: [
|
10
|
+
{
|
11
|
+
test: /\.(js|jsx)$/,
|
12
|
+
exclude: /node_modules/,
|
13
|
+
use: [
|
14
|
+
{
|
15
|
+
loader: 'babel-loader',
|
16
|
+
options: {
|
17
|
+
presets: [
|
18
|
+
'react',
|
19
|
+
'stage-2'
|
20
|
+
]
|
21
|
+
}
|
22
|
+
}
|
23
|
+
]
|
24
|
+
}
|
25
|
+
]
|
26
|
+
},
|
27
|
+
target: 'node',
|
28
|
+
output: {
|
29
|
+
path: path.resolve(__dirname, 'dist/bundles'),
|
30
|
+
filename: 'bundle.js',
|
31
|
+
libraryTarget: 'umd',
|
32
|
+
library: '@financial-times/n-myft-ui'
|
33
|
+
}
|
34
|
+
};
|
@@ -1,77 +0,0 @@
|
|
1
|
-
<section
|
2
|
-
class="collection {{#if liteStyle}}collection--lite{{else}}collection--regular{{/if}}"
|
3
|
-
data-trackable="{{#if trackable}}{{trackable}}{{else}}collection{{/if}}">
|
4
|
-
<header class="collection__header {{#if liteStyle}}collection__header--lite{{else}}collection__header--regular{{/if}}">
|
5
|
-
<h2 class="collection__title {{#if liteStyle}}collection__title--lite{{else}}collection__title--regular{{/if}}">
|
6
|
-
{{title}}
|
7
|
-
</h2>
|
8
|
-
</header>
|
9
|
-
<ul class="collection__concepts">
|
10
|
-
{{#concepts}}
|
11
|
-
<li class="collection__concept">
|
12
|
-
{{#if ../liteStyle}}
|
13
|
-
{{{renderReactComponent localPath="components/follow-button/follow-button" variant="primary" buttonText=name flags=@root.flags collectionName=../collectionName}}}
|
14
|
-
{{else}}
|
15
|
-
{{{renderReactComponent localPath="components/follow-button/follow-button" variant="inverse" buttonText=name flags=@root.flags collectionName=../collectionName}}}
|
16
|
-
{{/if}}
|
17
|
-
</li>
|
18
|
-
{{/concepts}}
|
19
|
-
</ul>
|
20
|
-
<div class="collection__meta">
|
21
|
-
<form
|
22
|
-
method="POST"
|
23
|
-
action="#"
|
24
|
-
data-myft-ui="follow"
|
25
|
-
{{#if collectionName}}data-myft-tracking="collectionName={{collectionName}}"{{/if}}
|
26
|
-
data-concept-id="
|
27
|
-
{{~#concepts~}}
|
28
|
-
{{conceptId}}
|
29
|
-
{{~#unless @last~}}
|
30
|
-
,
|
31
|
-
{{~/unless~}}
|
32
|
-
{{~/concepts~}}"
|
33
|
-
class="n-myft-ui n-myft-ui--follow n-ui-hide-core collection-follow-all">
|
34
|
-
<input
|
35
|
-
type="hidden"
|
36
|
-
name="directType"
|
37
|
-
value="
|
38
|
-
{{~#concepts~}}
|
39
|
-
{{directType}}
|
40
|
-
{{~#unless @last~}}
|
41
|
-
,
|
42
|
-
{{~/unless~}}
|
43
|
-
{{~/concepts~}}"
|
44
|
-
/>
|
45
|
-
{{{renderReactComponent localPath="components/csrf-token/input"}}}
|
46
|
-
<input
|
47
|
-
type="hidden"
|
48
|
-
name="name"
|
49
|
-
value="
|
50
|
-
{{~#concepts~}}
|
51
|
-
{{name}}
|
52
|
-
{{~#unless @last~}}
|
53
|
-
,
|
54
|
-
{{~/unless~}}
|
55
|
-
{{~/concepts~}}"
|
56
|
-
/>
|
57
|
-
<button
|
58
|
-
type="submit"
|
59
|
-
aria-pressed="false"
|
60
|
-
class="collection-follow-all__button {{#if liteStyle}}collection-follow-all__button--lite{{else}}collection-follow-all__button--regular{{/if}}"
|
61
|
-
data-trackable="follow all"
|
62
|
-
data-concept-id="
|
63
|
-
{{~#concepts~}}
|
64
|
-
{{conceptId}}
|
65
|
-
{{~#unless @last~}}
|
66
|
-
,
|
67
|
-
{{~/unless~}}
|
68
|
-
{{~/concepts~}}"
|
69
|
-
aria-label="Add all topics in the {{title}} collection to my F T"
|
70
|
-
data-alternate-label="Remove all topics in the {{title}} collection from my F T"
|
71
|
-
data-alternate-text="Added"
|
72
|
-
title="Add all topics in the {{title}} collection to my F T">
|
73
|
-
Add all to myFT
|
74
|
-
</button>
|
75
|
-
</form>
|
76
|
-
</div>
|
77
|
-
</section>
|
@@ -1,28 +0,0 @@
|
|
1
|
-
{{#ifAll @root.flags.myFtApi @root.flags.myFtApiWrite concepts concepts.length}}
|
2
|
-
<div
|
3
|
-
class="concept-list"
|
4
|
-
data-trackable="{{#if trackable}}{{trackable}}{{else}}concept-list{{/if}}">
|
5
|
-
{{#ifSome contentType conceptListTitle}}
|
6
|
-
<h2 class="concept-list__title">
|
7
|
-
{{#if conceptListTitle}}
|
8
|
-
{{conceptListTitle}}
|
9
|
-
{{else}}
|
10
|
-
Follow the topics in this {{contentType}}
|
11
|
-
{{/if}}
|
12
|
-
</h2>
|
13
|
-
{{/ifSome}}
|
14
|
-
<ul class="concept-list__list">
|
15
|
-
{{#each concepts}}
|
16
|
-
<li class="concept-list__list-item">
|
17
|
-
<a
|
18
|
-
href="{{relativeUrl}}"
|
19
|
-
data-trackable="{{#if conceptTrackable}}{{conceptTrackable}}{{else}}concept{{/if}}"
|
20
|
-
class="concept-list__concept">
|
21
|
-
{{prefLabel}}
|
22
|
-
</a>
|
23
|
-
{{{renderReactComponent localPath="components/follow-button/follow-button" conceptId=id name=prefLabel flags=@root.flags}}}
|
24
|
-
</li>
|
25
|
-
{{/each}}
|
26
|
-
</ul>
|
27
|
-
</div>
|
28
|
-
{{/ifAll}}
|
@@ -1,47 +0,0 @@
|
|
1
|
-
{{#if @root.flags.myFtApiWrite}}
|
2
|
-
<form class="n-myft-ui n-myft-ui--instant{{#if hideButtonText}} n-myft-ui--instant--hide-text{{/if}} {{extraClasses}}"
|
3
|
-
method="GET"
|
4
|
-
data-myft-ui="instant"
|
5
|
-
data-concept-id="{{conceptId}}"
|
6
|
-
action="/myft/add/{{conceptId}}?instant=true"
|
7
|
-
data-js-action="/__myft/api/core/followed/concept/{{conceptId}}?method=put">
|
8
|
-
{{{renderReactComponent localPath="components/csrf-token/input"}}}
|
9
|
-
<input type="hidden" value="{{name}}" name="name">
|
10
|
-
{{#if directType}}
|
11
|
-
<input type="hidden" value="{{directType}}" name="directType">
|
12
|
-
{{else}}
|
13
|
-
<input type="hidden" value="http://www.ft.com/ontology/concept/Concept" name="directType">
|
14
|
-
{{/if}}
|
15
|
-
<button
|
16
|
-
aria-label="Get instant alerts for {{name}}"
|
17
|
-
{{#ifAll hasInstantAlert @root.cacheablePersonalisedUrl}}
|
18
|
-
aria-pressed="true"
|
19
|
-
{{else}}
|
20
|
-
aria-pressed="false"
|
21
|
-
{{/ifAll}}
|
22
|
-
class="n-myft-ui__button
|
23
|
-
{{#variant}} n-myft-ui__button--{{this}}{{/variant}}
|
24
|
-
{{#size}} n-myft-ui__button--{{this}}{{/size}}
|
25
|
-
n-myft-ui__button--instant
|
26
|
-
n-myft-ui__button--instant-light"
|
27
|
-
data-alternate-label="Stop instant alerts for {{name}}"
|
28
|
-
{{#if alternateText}}
|
29
|
-
data-alternate-text="{{alternateText}}"
|
30
|
-
{{else}}
|
31
|
-
{{#if buttonText}}
|
32
|
-
data-alternate-text="{{buttonText}}"
|
33
|
-
{{else}}
|
34
|
-
data-alternate-text="Instant alerts"
|
35
|
-
{{/if}}
|
36
|
-
{{/if}}
|
37
|
-
data-concept-id="{{conceptId}}" {{! duplicated here for tracking}}
|
38
|
-
data-trackable="instant"
|
39
|
-
title="Get instant alerts for {{name}}"
|
40
|
-
name="_rel.instant"
|
41
|
-
value="{{#if hasInstantAlert}}false{{else}}true{{/if}}"
|
42
|
-
type="submit"
|
43
|
-
>{{#if buttonText}}{{buttonText}}{{else}}Instant alerts{{/if}}</button>
|
44
|
-
</form>
|
45
|
-
{{else}}
|
46
|
-
<!-- Instant alert button hidden due to myFtApiWrite being off -->
|
47
|
-
{{/if}}
|
@@ -1,20 +0,0 @@
|
|
1
|
-
{{#if showPrioritiseButton}}
|
2
|
-
<span class="myft-pin-divider"></span>
|
3
|
-
<div class="myft-pin-button-wrapper">
|
4
|
-
<form method="post" action="/__myft/api/core/prioritised/concept/{{id}}?method={{#if prioritised}}delete{{else}}put{{/if}}" data-myft-prioritise>
|
5
|
-
{{{renderReactComponent localPath="components/csrf-token/input"}}}
|
6
|
-
<input type="hidden" value="{{name}}" name="name"> {{#if directType}}
|
7
|
-
<input type="hidden" value="{{directType}}" name="directType"> {{else}}
|
8
|
-
<input type="hidden" value="http://www.ft.com/ontology/concept/Concept" name="directType"> {{/if}}
|
9
|
-
<div
|
10
|
-
class="n-myft-ui__announcement o-normalise-visually-hidden"
|
11
|
-
aria-live="assertive"
|
12
|
-
data-pressed-text="{{name}} pinned in myFT."
|
13
|
-
data-unpressed-text="Unpinned {{name}} from myFT."
|
14
|
-
></div>
|
15
|
-
<button id="myft-pin-button__{{id}}" class="myft-pin-button" data-prioritise-button data-trackable="prioritised" data-concept-id="{{id}}" data-prioritised="{{#if prioritised}}true{{else}}false{{/if}}"
|
16
|
-
aria-label="{{#if prioritised}}Unpin{{else}}Pin{{/if}} {{name}} {{#if prioritised}}from{{else}}in{{/if}} myFT" aria-pressed="{{#if prioritised}}true{{else}}false{{/if}}" title="{{#if prioritised}}Unpin{{else}}Pin{{/if}} {{name}}">
|
17
|
-
</button>
|
18
|
-
</form>
|
19
|
-
</div>
|
20
|
-
{{/if}}
|
@@ -1,67 +0,0 @@
|
|
1
|
-
{{#if @root.flags.myFtApiWrite}}
|
2
|
-
<form class="n-myft-ui n-myft-ui--save" method="GET"
|
3
|
-
data-content-id="{{contentId}}"
|
4
|
-
data-myft-ui="saved"
|
5
|
-
action="/myft/save/{{contentId}}"
|
6
|
-
data-js-action="/__myft/api/core/saved/content/{{contentId}}?method=put">
|
7
|
-
{{{renderReactComponent localPath="components/csrf-token/input"}}}
|
8
|
-
<div
|
9
|
-
class="n-myft-ui__announcement o-normalise-visually-hidden"
|
10
|
-
aria-live="assertive"
|
11
|
-
data-pressed-text="Article saved in My FT."
|
12
|
-
data-unpressed-text="Removed article from My FT."
|
13
|
-
></div>
|
14
|
-
<button
|
15
|
-
type="submit"
|
16
|
-
class="{{#if saveButtonWithIcon}}n-myft-ui__save-button-with-icon{{else}}n-myft-ui__button{{#variant}} n-myft-ui__button--{{this}}{{/variant}}{{/if}}"
|
17
|
-
data-trackable="{{#if trackableId}}{{trackableId}}{{else}}save-for-later{{/if}}"
|
18
|
-
{{#if isSaved}}
|
19
|
-
{{!-- The value of alternate label needs to be the opposite of label / the current saved state. This allows the client side JS to toggle the labels on state changes --}}
|
20
|
-
title="{{#if title}}{{title}} is{{/if}} Saved to myFT"
|
21
|
-
aria-label="{{#if title}}{{title}} is{{/if}} Saved to myFT"
|
22
|
-
data-alternate-label="{{#if title}}Save {{title}} to myFT for later{{else}}Save this article to myFT for later{{/if}}"
|
23
|
-
aria-pressed="true"
|
24
|
-
{{else}}
|
25
|
-
title="{{#if title}}Save {{title}} to myFT for later{{else}}Save this article to myFT for later{{/if}}"
|
26
|
-
aria-label="{{#if title}}Save {{title}} to myFT for later{{else}}Save this article to myFT for later{{/if}}"
|
27
|
-
data-alternate-label="{{#if title}}{{title}} is{{/if}} Saved to myFT"
|
28
|
-
aria-pressed="false"
|
29
|
-
{{/if}}
|
30
|
-
{{#unlessEquals appIsStreamPage true}}
|
31
|
-
{{#if saveButtonWithIcon}}
|
32
|
-
data-text-variant="save-button-with-icon-copy"
|
33
|
-
{{else}}
|
34
|
-
data-text-variant="save-button-longer-copy"
|
35
|
-
{{/if}}
|
36
|
-
{{/unlessEquals}}
|
37
|
-
{{#if alternateText}}
|
38
|
-
data-alternate-text="{{alternateText}}"
|
39
|
-
{{else}}
|
40
|
-
{{#if isSaved}}
|
41
|
-
data-alternate-text="Save "
|
42
|
-
{{else}}
|
43
|
-
data-alternate-text="Saved "
|
44
|
-
{{/if}}
|
45
|
-
{{/if}}
|
46
|
-
data-content-id="{{contentId}}" {{! duplicated here for tracking}}
|
47
|
-
>
|
48
|
-
{{#if saveButtonWithIcon}}
|
49
|
-
<span class="save-button-with-icon-copy" data-variant-label>{{#if buttonText~}}
|
50
|
-
{{buttonText}}
|
51
|
-
{{~else~}}
|
52
|
-
{{#if isSaved}}Saved{{else}}Save{{/if}}
|
53
|
-
{{~/if}}</span>
|
54
|
-
{{else}}
|
55
|
-
{{#if buttonText}}{{buttonText}}{{else}}
|
56
|
-
{{#unlessEquals appIsStreamPage true}}
|
57
|
-
<span class="save-button-longer-copy" data-variant-label>{{#if isSaved}}Saved {{else}}Save {{/if}}</span><span class="n-myft-ui__button--viewport-large" aria-hidden="true">to myFT</span>
|
58
|
-
{{else}}
|
59
|
-
<span>{{#if isSaved}}Saved{{else}}Save{{/if}}</span>
|
60
|
-
{{/unlessEquals}}
|
61
|
-
{{/if}}
|
62
|
-
{{/if}}
|
63
|
-
</button>
|
64
|
-
</form>
|
65
|
-
{{else}}
|
66
|
-
<!-- Save button hidden due to myFtApiWrite being off -->
|
67
|
-
{{/if }}
|