@financial-times/n-myft-ui 26.0.0 → 27.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. package/.circleci/config.yml +42 -16
  2. package/.nvmrc +1 -1
  3. package/Makefile +0 -1
  4. package/README.md +2 -48
  5. package/build-state/npm-shrinkwrap.json +10147 -20187
  6. package/components/collections/collections.html +85 -0
  7. package/components/concept-list/concept-list.html +31 -0
  8. package/components/csrf-token/input.html +5 -0
  9. package/components/follow-button/follow-button.html +79 -0
  10. package/components/instant-alert/instant-alert.html +47 -0
  11. package/components/pin-button/pin-button.html +20 -0
  12. package/components/save-for-later/save-for-later.html +68 -0
  13. package/components/unread-articles-indicator/date-fns.js +6 -6
  14. package/demos/app.js +3 -26
  15. package/demos/templates/demo.html +11 -10
  16. package/myft/main.scss +145 -0
  17. package/myft/ui/lists.js +22 -0
  18. package/myft/ui/save-article-to-list-variant.js +376 -0
  19. package/package.json +16 -30
  20. package/components/collections/collections.jsx +0 -68
  21. package/components/collections/collections.test.js +0 -83
  22. package/components/concept-list/concept-list.jsx +0 -69
  23. package/components/concept-list/concept-list.test.js +0 -116
  24. package/components/csrf-token/input.jsx +0 -20
  25. package/components/csrf-token/input.test.js +0 -23
  26. package/components/follow-button/follow-button.jsx +0 -176
  27. package/components/follow-button/follow-button.test.js +0 -40
  28. package/components/index.js +0 -17
  29. package/components/instant-alert/instant-alert.jsx +0 -73
  30. package/components/instant-alert/instant-alert.test.js +0 -86
  31. package/components/pin-button/pin-button.jsx +0 -40
  32. package/components/pin-button/pin-button.test.js +0 -57
  33. package/components/save-for-later/save-for-later.jsx +0 -101
  34. package/components/save-for-later/save-for-later.test.js +0 -59
  35. package/demos/templates/demo-layout.html +0 -25
  36. package/demos/templates/demo.jsx +0 -125
  37. package/dist/bundles/bundle.js +0 -3232
  38. package/jest.config.js +0 -8
  39. package/jsx-migration.md +0 -16
  40. package/webpack.config.js +0 -34
@@ -0,0 +1,85 @@
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
+ {{> n-myft-ui/components/follow-button/follow-button
14
+ variant="primary"
15
+ buttonText=name
16
+ collectionName=../collectionName
17
+ }}
18
+ {{else}}
19
+ {{> n-myft-ui/components/follow-button/follow-button
20
+ variant="inverse"
21
+ buttonText=name
22
+ collectionName=../collectionName
23
+ }}
24
+ {{/if}}
25
+ </li>
26
+ {{/concepts}}
27
+ </ul>
28
+ <div class="collection__meta">
29
+ <form
30
+ method="POST"
31
+ action="#"
32
+ data-myft-ui="follow"
33
+ {{#if collectionName}}data-myft-tracking="collectionName={{collectionName}}"{{/if}}
34
+ data-concept-id="
35
+ {{~#concepts~}}
36
+ {{conceptId}}
37
+ {{~#unless @last~}}
38
+ ,
39
+ {{~/unless~}}
40
+ {{~/concepts~}}"
41
+ class="n-myft-ui n-myft-ui--follow n-ui-hide-core collection-follow-all">
42
+ <input
43
+ type="hidden"
44
+ name="directType"
45
+ value="
46
+ {{~#concepts~}}
47
+ {{directType}}
48
+ {{~#unless @last~}}
49
+ ,
50
+ {{~/unless~}}
51
+ {{~/concepts~}}"
52
+ />
53
+ {{> n-myft-ui/components/csrf-token/input}}
54
+ <input
55
+ type="hidden"
56
+ name="name"
57
+ value="
58
+ {{~#concepts~}}
59
+ {{name}}
60
+ {{~#unless @last~}}
61
+ ,
62
+ {{~/unless~}}
63
+ {{~/concepts~}}"
64
+ />
65
+ <button
66
+ type="submit"
67
+ aria-pressed="false"
68
+ class="collection-follow-all__button {{#if liteStyle}}collection-follow-all__button--lite{{else}}collection-follow-all__button--regular{{/if}}"
69
+ data-trackable="follow all"
70
+ data-concept-id="
71
+ {{~#concepts~}}
72
+ {{conceptId}}
73
+ {{~#unless @last~}}
74
+ ,
75
+ {{~/unless~}}
76
+ {{~/concepts~}}"
77
+ aria-label="Add all topics in the {{title}} collection to my F T"
78
+ data-alternate-label="Remove all topics in the {{title}} collection from my F T"
79
+ data-alternate-text="Added"
80
+ title="Add all topics in the {{title}} collection to my F T">
81
+ Add all to myFT
82
+ </button>
83
+ </form>
84
+ </div>
85
+ </section>
@@ -0,0 +1,31 @@
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
+ {{> n-myft-ui/components/follow-button/follow-button
24
+ conceptId=id
25
+ name=prefLabel
26
+ }}
27
+ </li>
28
+ {{/each}}
29
+ </ul>
30
+ </div>
31
+ {{/ifAll}}
@@ -0,0 +1,5 @@
1
+ <input
2
+ data-myft-csrf-token
3
+ value="{{#if @root.cacheablePersonalisedUrl}}{{@root.csrfToken}}{{/if}}"
4
+ type="hidden"
5
+ name="token">
@@ -0,0 +1,79 @@
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}}
@@ -0,0 +1,47 @@
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
+ {{> n-myft-ui/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}}
@@ -0,0 +1,20 @@
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
+ {{> n-myft-ui/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}}
@@ -0,0 +1,68 @@
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
+ {{#ifEquals @root.flags.professorLists 'variant'}}data-myft-ui-variant="createListAndSaveArticleVariant"{{/ifEquals}}>
8
+ {{> n-myft-ui/components/csrf-token/input}}
9
+ <div
10
+ class="n-myft-ui__announcement o-normalise-visually-hidden"
11
+ aria-live="assertive"
12
+ data-pressed-text="Article saved in My FT."
13
+ data-unpressed-text="Removed article from My FT."
14
+ ></div>
15
+ <button
16
+ type="submit"
17
+ class="{{#if saveButtonWithIcon}}n-myft-ui__save-button-with-icon{{else}}n-myft-ui__button{{#variant}} n-myft-ui__button--{{this}}{{/variant}}{{/if}}"
18
+ data-trackable="{{#if trackableId}}{{trackableId}}{{else}}save-for-later{{/if}}"
19
+ {{#if isSaved}}
20
+ {{!-- 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 --}}
21
+ title="{{#if title}}{{title}} is{{/if}} Saved to myFT"
22
+ aria-label="{{#if title}}{{title}} is{{/if}} Saved to myFT"
23
+ data-alternate-label="{{#if title}}Save {{title}} to myFT for later{{else}}Save this article to myFT for later{{/if}}"
24
+ aria-pressed="true"
25
+ {{else}}
26
+ title="{{#if title}}Save {{title}} to myFT for later{{else}}Save this article to myFT for later{{/if}}"
27
+ aria-label="{{#if title}}Save {{title}} to myFT for later{{else}}Save this article to myFT for later{{/if}}"
28
+ data-alternate-label="{{#if title}}{{title}} is{{/if}} Saved to myFT"
29
+ aria-pressed="false"
30
+ {{/if}}
31
+ {{#unlessEquals appIsStreamPage true}}
32
+ {{#if saveButtonWithIcon}}
33
+ data-text-variant="save-button-with-icon-copy"
34
+ {{else}}
35
+ data-text-variant="save-button-longer-copy"
36
+ {{/if}}
37
+ {{/unlessEquals}}
38
+ {{#if alternateText}}
39
+ data-alternate-text="{{alternateText}}"
40
+ {{else}}
41
+ {{#if isSaved}}
42
+ data-alternate-text="Save&nbsp;"
43
+ {{else}}
44
+ data-alternate-text="Saved&nbsp;"
45
+ {{/if}}
46
+ {{/if}}
47
+ data-content-id="{{contentId}}" {{! duplicated here for tracking}}
48
+ >
49
+ {{#if saveButtonWithIcon}}
50
+ <span class="save-button-with-icon-copy" data-variant-label>{{#if buttonText~}}
51
+ {{buttonText}}
52
+ {{~else~}}
53
+ {{#if isSaved}}Saved{{else}}Save{{/if}}
54
+ {{~/if}}</span>
55
+ {{else}}
56
+ {{#if buttonText}}{{buttonText}}{{else}}
57
+ {{#unlessEquals appIsStreamPage true}}
58
+ <span class="save-button-longer-copy" data-variant-label>{{#if isSaved}}Saved&nbsp;{{else}}Save&nbsp;{{/if}}</span><span class="n-myft-ui__button--viewport-large" aria-hidden="true">to myFT</span>
59
+ {{else}}
60
+ <span>{{#if isSaved}}Saved{{else}}Save{{/if}}</span>
61
+ {{/unlessEquals}}
62
+ {{/if}}
63
+ {{/if}}
64
+ </button>
65
+ </form>
66
+ {{else}}
67
+ <!-- Save button hidden due to myFtApiWrite being off -->
68
+ {{/if }}
@@ -2,12 +2,12 @@
2
2
  // the detail => https://github.com/date-fns/date-fns/blob/HEAD/CHANGELOG.md#200---2019-08-20
3
3
  // By adding validation for dates before their functions allows us to know it when unexpected value passed.
4
4
 
5
- import isTodayOriginal from 'date-fns/src/isToday';
6
- import isAfterOriginal from 'date-fns/src/isAfter';
7
- import addMinutesOriginal from 'date-fns/src/addMinutes';
8
- import startOfDayOriginal from 'date-fns/src/startOfDay';
9
- import isValidOriginal from 'date-fns/src/isValid';
10
- import parseISO from 'date-fns/src/parseISO';
5
+ import isTodayOriginal from "date-fns/src/isToday";
6
+ import isAfterOriginal from "date-fns/src/isAfter";
7
+ import addMinutesOriginal from "date-fns/src/addMinutes";
8
+ import startOfDayOriginal from "date-fns/src/startOfDay";
9
+ import isValidOriginal from "date-fns/src/isValid";
10
+ import parseISO from "date-fns/src/parseISO";
11
11
 
12
12
  const isValid = (date) => {
13
13
  if (!isValidOriginal(date)) {
package/demos/app.js CHANGED
@@ -1,17 +1,11 @@
1
- require('sucrase/register');
2
1
  const nExpress = require('@financial-times/n-express');
3
2
  const chalk = require('chalk');
4
3
  const errorHighlight = chalk.bold.red;
5
4
  const highlight = chalk.bold.green;
6
- const { PageKitReactJSX } = require('@financial-times/dotcom-server-react-jsx');
7
- const fs = require('fs');
8
5
  const path = require('path');
9
6
  const handlebars = require('handlebars');
10
7
  const { PageKitHandlebars, helpers } = require('@financial-times/dotcom-server-handlebars');
11
8
 
12
- const demoJSX = require('./templates/demo').default;
13
- const demoLayoutSource = fs.readFileSync(path.join(__dirname, './templates/demo-layout.html'),'utf8').toString();
14
-
15
9
  const fixtures = {
16
10
  followButton: require('./fixtures/follow-button'),
17
11
  saveButton: require('./fixtures/save-button'),
@@ -37,43 +31,26 @@ const app = module.exports = nExpress({
37
31
 
38
32
  app.set('views', path.join(__dirname, '/templates'));
39
33
  app.set('view engine', '.html');
40
-
41
34
  app.engine('.html', new PageKitHandlebars({
42
35
  cache: false,
43
36
  handlebars,
44
- helpers
37
+ helpers: {
38
+ ...helpers
39
+ }
45
40
  }).engine);
46
41
 
47
42
  app.use('/public', nExpress.static(path.join(__dirname, '../public'), { redirect: false }));
48
43
 
49
- const jsxRenderer = (new PageKitReactJSX({ includeDoctype: false }));
50
-
51
44
  app.get('/', (req, res) => {
52
45
  res.render('demo', Object.assign({
53
- title: 'n-myft-ui demo',
54
- flags: {
55
- myFtApi: true,
56
- myFtApiWrite: true
57
- },
58
- }, fixtures));
59
- });
60
-
61
- app.get('/demo-jsx', async (req, res) => {
62
- let demo = await jsxRenderer.render(demoJSX, Object.assign({
63
46
  title: 'n-myft-ui demo',
64
47
  flags: {
65
48
  myFtApi: true,
66
49
  myFtApiWrite: true
67
50
  }
68
51
  }, fixtures));
69
-
70
- let template = handlebars.compile(demoLayoutSource);
71
- let result = template({body: demo});
72
-
73
- res.send(result);
74
52
  });
75
53
 
76
-
77
54
  function runPa11yTests () {
78
55
  const spawn = require('child_process').spawn;
79
56
  const pa11y = spawn('pa11y-ci');
@@ -32,7 +32,7 @@
32
32
  </h2>
33
33
 
34
34
  {{#followButton}}
35
- {{{renderReactComponent localPath="components/follow-button/follow-button" flags=@root.flags}}}
35
+ {{> n-myft-ui/components/follow-button/follow-button}}
36
36
  {{/followButton}}
37
37
 
38
38
  <h2
@@ -41,51 +41,52 @@
41
41
  </h2>
42
42
 
43
43
  {{#followButton}}
44
- {{{renderReactComponent localPath="components/follow-button/follow-button" buttonText=name flags=@root.flags}}}
44
+ {{> n-myft-ui/components/follow-button/follow-button buttonText=name}}
45
45
  {{/followButton}}
46
46
 
47
47
  {{#saveButton}}
48
48
  <h2 class="demo-section__title">
49
49
  Save button
50
50
  </h2>
51
- {{{renderReactComponent localPath="components/save-for-later/save-for-later" flags=@root.flags title=title contentId=contentId }}}
51
+ {{> n-myft-ui/components/save-for-later/save-for-later }}
52
52
  {{/saveButton}}
53
53
 
54
54
  {{#saveButton}}
55
55
  <h2 class="demo-section__title">
56
56
  Unsave button
57
57
  </h2>
58
- {{{renderReactComponent localPath="components/save-for-later/save-for-later" flags=@root.flags title=title contentId=contentId isSaved=true }}}
58
+ {{> n-myft-ui/components/save-for-later/save-for-later isSaved=true }}
59
59
  {{/saveButton}}
60
60
 
61
61
  {{#saveButton}}
62
62
  <h2 class="demo-section__title">
63
63
  Save button with icon
64
64
  </h2>
65
- {{{renderReactComponent localPath="components/save-for-later/save-for-later" flags=@root.flags title=title contentId=contentId saveButtonWithIcon=true }}}
65
+ {{> n-myft-ui/components/save-for-later/save-for-later saveButtonWithIcon=true }}
66
66
  {{/saveButton}}
67
67
 
68
68
  {{#saveButton}}
69
69
  <h2 class="demo-section__title">
70
70
  Unsave button with icon
71
71
  </h2>
72
- {{{renderReactComponent localPath="components/save-for-later/save-for-later" flags=@root.flags title=title contentId=contentId saveButtonWithIcon=true isSaved=true }}}
72
+ {{> n-myft-ui/components/save-for-later/save-for-later isSaved=true saveButtonWithIcon=true }}
73
73
  {{/saveButton}}
74
74
 
75
75
  <h2 class="demo-section__title">
76
76
  Pin button
77
77
  </h2>
78
78
  {{#each pinButton}}
79
- {{{renderReactComponent localPath="components/pin-button/pin-button" flags=@root.flags title=title id=id name=name directType=directType showPrioritiseButton=showPrioritiseButton }}}
79
+ {{> n-myft-ui/components/pin-button/pin-button }}
80
80
  {{/each}}
81
81
 
82
82
  {{#instantAlert}}
83
83
  <h2 class="demo-section__title">
84
84
  Instant Alert
85
85
  </h2>
86
- {{{renderReactComponent localPath="components/instant-alert/instant-alert" flags=@root.flags title=title conceptId=id name=name directType=directType }}}
86
+ {{> n-myft-ui/components/instant-alert/instant-alert }}
87
87
  {{/instantAlert}}
88
88
 
89
+
89
90
  </div>
90
91
  </div>
91
92
  </section>
@@ -448,7 +449,7 @@
448
449
 
449
450
  {{#collections}}
450
451
  <div data-o-grid-colspan="3">
451
- {{{renderReactComponent localPath="components/collections/collections" flags=@root.flags concepts=this.concepts title=this.title liteStyle=this.liteStyle collectionName=this.collectionName trackable=this.trackable}}}
452
+ {{> n-myft-ui/components/collections/collections }}
452
453
  </div>
453
454
  {{/collections}}
454
455
  </div>
@@ -470,7 +471,7 @@
470
471
 
471
472
  {{#each conceptList}}
472
473
  <div data-o-grid-colspan="3">
473
- {{{renderReactComponent localPath="components/concept-list/concept-list" flags=@root.flags concepts=this.concepts contentType=this.contentType conceptListTitle=this.conceptListTitle trackable=this.trackable}}}
474
+ {{> n-myft-ui/components/concept-list/concept-list }}
474
475
  </div>
475
476
  {{/each}}
476
477
  </div>
package/myft/main.scss CHANGED
@@ -173,3 +173,148 @@ $spacing-unit: 20px;
173
173
  }
174
174
 
175
175
  }
176
+
177
+ .share-nav {
178
+ &.data-overlap-initialised {
179
+ .o-overlay {
180
+ transition: opacity 0.15s ease-in;
181
+ opacity: 0;
182
+ z-index: -1;
183
+ }
184
+ }
185
+
186
+ .myft-ui-create-list-variant {
187
+ border-radius: 10px;
188
+ border: 1px solid oColorsByName('black-5');
189
+ background: oColorsByName('white-80');
190
+
191
+ .o-overlay__heading {
192
+ border-radius: 10px 10px 0 0;
193
+ background: oColorsByName('white-60');
194
+ @include oTypographySans($scale: 2);
195
+ color: oColorsByName('black-80');
196
+ }
197
+
198
+ .o-overlay__content {
199
+ @include oTypographySans($scale: 0);
200
+ color: oColorsByName('black-80');
201
+ padding: 0;
202
+ }
203
+
204
+ .o-overlay__title {
205
+ margin: 8px 14px 0 8px;
206
+ }
207
+
208
+ &-container {
209
+ display: block;
210
+ width: 340px;
211
+ top: 115.5px;
212
+ left: 50px;
213
+ }
214
+
215
+ &-add {
216
+ border: 0;
217
+ background: none;
218
+ @include oTypographySans($scale: 1, $weight: 'semibold');
219
+ color: oColorsByName('black-80');
220
+
221
+ padding-left: 0;
222
+ margin-left: -8px;
223
+
224
+ &:hover {
225
+ text-decoration: underline;
226
+ }
227
+
228
+ &::before {
229
+ content: '';
230
+ @include oIconsContent(
231
+ 'plus',
232
+ oColorsByName('black-80'),
233
+ 28,
234
+ $iconset-version: 1
235
+ );
236
+ vertical-align: middle;
237
+ margin-top: -2px;
238
+ }
239
+ }
240
+
241
+ &-add-description {
242
+ margin: 4px 0;
243
+ }
244
+
245
+ &-heading {
246
+ &::before {
247
+ content: '';
248
+ @include oIconsContent(
249
+ 'tick',
250
+ oColorsByName('teal'),
251
+ 32,
252
+ $iconset-version: 1
253
+ );
254
+ vertical-align: middle;
255
+ margin-top: -2px;
256
+ }
257
+ }
258
+
259
+ &-footer {
260
+ border-top: 1px solid oColorsByName('black-5');
261
+ padding: 16px;
262
+ }
263
+
264
+ &-icon {
265
+ &::before {
266
+ content: "";
267
+ display: inline-block;
268
+ background-repeat: no-repeat;
269
+ background-size: contain;
270
+ background-position: 50%;
271
+ background-color: transparent;
272
+ background-image: url(https://www.ft.com/__origami/service/image/v2/images/raw/ftlogo-v1:brand-myft?source=next-article);
273
+ width: 42px;
274
+ height: 42px;
275
+ vertical-align: middle;
276
+ margin-top: -2px;
277
+ }
278
+
279
+ &-visually-hidden {
280
+ clip: rect(0 0 0 0);
281
+ clip-path: inset(50%);
282
+ height: 1px;
283
+ overflow: hidden;
284
+ position: absolute;
285
+ white-space: nowrap;
286
+ width: 1px;
287
+ }
288
+ }
289
+
290
+ &-form {
291
+ display: flex;
292
+ width: calc(100% - 32px);
293
+ justify-content: space-between;
294
+ height: 40px;
295
+ gap: 8px;
296
+ padding: 0 16px 16px;
297
+
298
+ & > * {
299
+ flex: 1 1 auto;
300
+ }
301
+
302
+ .o-forms-input {
303
+ margin-top: 0;
304
+ }
305
+ }
306
+
307
+ &-lists {
308
+ padding: 16px 16px 0;
309
+ @include oTypographySans($scale: 1);
310
+ &-text {
311
+ @include oTypographySans($weight: 'semibold');
312
+ color: oColorsByName('black-80');
313
+ margin-bottom: 16px;
314
+ }
315
+ &-container {
316
+ margin-top: 0;
317
+ }
318
+ }
319
+ }
320
+ }