@financial-times/n-myft-ui 28.3.3 → 29.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,8 +4,8 @@
4
4
  data-myft-ui="saved"
5
5
  action="/myft/save/{{contentId}}"
6
6
  data-js-action="/__myft/api/core/saved/content/{{contentId}}?method=put"
7
- {{#if flags.manageArticleLists}}data-myft-ui-save-new="manageArticleLists"{{/if}}
8
- {{#if flags.manageArticleLists}}data-myft-ui-save-new-config="{{#if flags.myftListPublicPrivateToggle}}showPublicToggle{{/if}}"{{/if}}>
7
+ {{#if @root.flags.manageArticleLists}}data-myft-ui-save-new="manageArticleLists"{{/if}}
8
+ {{#if @root.flags.manageArticleLists}}data-myft-ui-save-new-config="{{#if @root.flags.myftListPublicPrivateToggle}}showPublicToggle{{/if}},{{#if modal}}modal{{/if}}"{{/if}}>
9
9
  {{> n-myft-ui/components/csrf-token/input}}
10
10
  <div
11
11
  class="n-myft-ui__announcement o-normalise-visually-hidden"
package/myft/main.scss CHANGED
@@ -24,6 +24,17 @@ $spacing-unit: 20px;
24
24
  display: inline-block;
25
25
  }
26
26
 
27
+ // article lists modal
28
+ @include oForms($opts: (
29
+ 'elements': ('text', 'checkbox', 'toggle')
30
+ ));
31
+
32
+ @include oButtons($opts: (
33
+ 'sizes': ('big'),
34
+ 'types': ('primary', 'secondary'),
35
+ 'themes': ('inverse')
36
+ ));
37
+
27
38
  // experimental flash animation on header icon
28
39
  @include myftHeaderIconFlash;
29
40
 
@@ -174,196 +185,198 @@ $spacing-unit: 20px;
174
185
 
175
186
  }
176
187
 
177
- .share-nav {
178
- &.data-overlap-initialised {
179
- .o-overlay {
180
- transition: opacity 0.15s ease-in;
181
- opacity: 0;
182
- z-index: -1;
188
+ .myft-ui-create-list-variant-message {
189
+ border-radius: 10px;
190
+ border: 1px solid oColorsByName('black-5');
191
+ background: oColorsByName('white-80');
192
+
193
+ &-content {
194
+ display: flex;
195
+ flex-direction: column;
196
+
197
+ h3 {
198
+ margin: 0;
183
199
  }
184
200
  }
185
201
 
186
- .myft-ui-create-list-variant-message {
187
- border-radius: 10px;
188
- border: 1px solid oColorsByName('black-5');
189
- background: oColorsByName('white-80');
202
+ &-buttons {
203
+ text-align: center;
204
+ }
205
+ }
190
206
 
191
- &-content {
192
- display: flex;
193
- flex-direction: column;
207
+ .myft-ui-create-list-variant {
208
+ border-radius: 10px;
209
+ border: 1px solid oColorsByName('black-5');
210
+ background: oColorsByName('white-80');
194
211
 
195
- h3 {
196
- margin: 0;
197
- }
198
- }
212
+ .o-overlay__heading {
213
+ border-radius: 10px 10px 0 0;
214
+ background: oColorsByName('white-60');
215
+ @include oTypographySans($scale: 2);
216
+ color: oColorsByName('black-80');
217
+ }
199
218
 
200
- &-buttons {
201
- text-align: center;
202
- }
219
+ .o-overlay__content {
220
+ @include oTypographySans($scale: 0);
221
+ color: oColorsByName('black-80');
222
+ padding: 0;
203
223
  }
204
224
 
225
+ .o-overlay__title {
226
+ margin: 8px 14px 0 8px;
227
+ }
205
228
 
206
- .myft-ui-create-list-variant {
207
- border-radius: 10px;
208
- border: 1px solid oColorsByName('black-5');
209
- background: oColorsByName('white-80');
229
+ &-container {
230
+ display: block;
231
+ width: 340px;
232
+ top: 115.5px;
233
+ left: 50px;
234
+ }
210
235
 
211
- .o-overlay__heading {
212
- border-radius: 10px 10px 0 0;
213
- background: oColorsByName('white-60');
214
- @include oTypographySans($scale: 2);
215
- color: oColorsByName('black-80');
216
- }
236
+ &-add {
237
+ border: 0;
238
+ background: none;
239
+ @include oTypographySans($scale: 1, $weight: 'semibold');
240
+ color: oColorsByName('black-80');
217
241
 
218
- .o-overlay__content {
219
- @include oTypographySans($scale: 0);
220
- color: oColorsByName('black-80');
221
- padding: 0;
222
- }
242
+ padding-left: 0;
223
243
 
224
- .o-overlay__title {
225
- margin: 8px 14px 0 8px;
244
+ &:hover {
245
+ text-decoration: underline;
226
246
  }
227
247
 
228
- &-container {
229
- display: block;
230
- width: 340px;
231
- top: 115.5px;
232
- left: 50px;
248
+ &-collapsed::before {
249
+ content: '';
250
+ @include oIconsContent(
251
+ 'plus',
252
+ oColorsByName('black-80'),
253
+ 28,
254
+ $iconset-version: 1
255
+ );
256
+ vertical-align: middle;
257
+ margin-top: -2px;
258
+ margin-left: -8px;
233
259
  }
260
+ }
234
261
 
235
- &-add {
236
- border: 0;
237
- background: none;
238
- @include oTypographySans($scale: 1, $weight: 'semibold');
239
- color: oColorsByName('black-80');
240
-
241
- padding-left: 0;
242
-
243
- &:hover {
244
- text-decoration: underline;
245
- }
262
+ &-add-description {
263
+ margin: oSpacingByName('s1') 0;
264
+ }
246
265
 
247
- &-collapsed::before {
248
- content: '';
249
- @include oIconsContent(
250
- 'plus',
251
- oColorsByName('black-80'),
252
- 28,
253
- $iconset-version: 1
266
+ &-heading {
267
+ &::before {
268
+ content: '';
269
+ @include oIconsContent(
270
+ 'tick',
271
+ oColorsByName('teal'),
272
+ 32,
273
+ $iconset-version: 1
254
274
  );
255
275
  vertical-align: middle;
256
276
  margin-top: -2px;
257
- margin-left: -8px;
258
277
  }
259
278
  }
260
279
 
261
- &-add-description {
262
- margin: oSpacingByName('s1') 0;
263
- }
280
+ &-footer {
281
+ border-top: 1px solid oColorsByName('black-5');
282
+ padding: oSpacingByName('s4');
283
+ }
264
284
 
265
- &-heading {
266
- &::before {
267
- content: '';
268
- @include oIconsContent(
269
- 'tick',
270
- oColorsByName('teal'),
271
- 32,
272
- $iconset-version: 1
273
- );
274
- vertical-align: middle;
275
- margin-top: -2px;
276
- }
285
+ &-icon {
286
+ &::before {
287
+ content: "";
288
+ display: inline-block;
289
+ background-repeat: no-repeat;
290
+ background-size: contain;
291
+ background-position: 50%;
292
+ background-color: transparent;
293
+ background-image: url(https://www.ft.com/__origami/service/image/v2/images/raw/ftlogo-v1:brand-myft?source=next-article);
294
+ width: 42px;
295
+ height: 42px;
296
+ vertical-align: middle;
297
+ margin-top: -2px;
277
298
  }
278
299
 
279
- &-footer {
280
- border-top: 1px solid oColorsByName('black-5');
281
- padding: oSpacingByName('s4');
300
+ &-visually-hidden {
301
+ clip: rect(0 0 0 0);
302
+ clip-path: inset(50%);
303
+ height: 1px;
304
+ overflow: hidden;
305
+ position: absolute;
306
+ white-space: nowrap;
307
+ width: 1px;
308
+ }
282
309
  }
283
310
 
284
- &-icon {
285
- &::before {
286
- content: "";
287
- display: inline-block;
288
- background-repeat: no-repeat;
289
- background-size: contain;
290
- background-position: 50%;
291
- background-color: transparent;
292
- background-image: url(https://www.ft.com/__origami/service/image/v2/images/raw/ftlogo-v1:brand-myft?source=next-article);
293
- width: 42px;
294
- height: 42px;
295
- vertical-align: middle;
296
- margin-top: -2px;
297
- }
298
-
299
- &-visually-hidden {
300
- clip: rect(0 0 0 0);
301
- clip-path: inset(50%);
302
- height: 1px;
303
- overflow: hidden;
304
- position: absolute;
305
- white-space: nowrap;
306
- width: 1px;
307
- }
311
+ &-form {
312
+ $field-spacing: 's4';
313
+ display: flex;
314
+ flex-direction: column;
315
+ width: calc(100% - 32px);
316
+ gap: oSpacingByName($field-spacing);
317
+ padding: 0 oSpacingByName($field-spacing) oSpacingByName('s3');
318
+
319
+ & >* {
320
+ flex: 1 1 auto;
321
+ margin-bottom: 0;
308
322
  }
309
323
 
310
- &-form {
311
- $field-spacing: 's4';
312
- display: flex;
313
- flex-direction: column;
314
- width: calc(100% - 32px);
315
- gap: oSpacingByName($field-spacing);
316
- padding: 0 oSpacingByName($field-spacing) oSpacingByName('s3');
317
-
318
- & > * {
319
- flex: 1 1 auto;
320
- margin-bottom: 0;
321
- }
324
+ & >*.o-forms-field {
325
+ margin-bottom: 0;
326
+ }
322
327
 
323
- .o-forms-input {
324
- margin-top: 0;
325
- }
328
+ .o-forms-input {
329
+ margin-top: 0;
330
+ }
326
331
 
327
- &-toggle {
328
- position: absolute;
329
- }
332
+ &-toggle {
333
+ position: absolute;
334
+ }
330
335
 
331
- &-toggle-label::after {
332
- background-color: oColorsByName('white');
333
- }
336
+ &-toggle-label.o-forms-input__label::after {
337
+ background-color: oColorsByName('white');
338
+ }
334
339
 
335
- &-buttons {
336
- display: flex;
337
- justify-content: flex-end;
338
- @include oTypographySans($scale: 2);
339
- }
340
+ &-buttons {
341
+ display: flex;
342
+ justify-content: flex-end;
343
+ @include oTypographySans($scale: 2);
344
+ }
340
345
 
341
- &-public {
342
- max-width: 300px;
343
- padding: 0 3px;
344
- }
346
+ &-public {
347
+ max-width: 300px;
348
+ padding: 0 3px;
345
349
  }
350
+ }
346
351
 
347
- &-lists {
348
- padding: oSpacingByName('s4') oSpacingByName('s4') 0;
349
- @include oTypographySans($scale: 1);
350
- &-text {
351
- @include oTypographySans($weight: 'semibold');
352
- color: oColorsByName('black-80');
353
- margin-bottom: oSpacingByName('s3');
354
- }
355
- &-container {
356
- margin-top: 0;
357
- max-height: 92px;
358
- padding: 4px 2px;
359
- overflow-y: auto;
360
- @include oGridRespondTo($from: M) {
361
- max-height: 126px;
362
- }
352
+ &-lists {
353
+ padding: oSpacingByName('s4') oSpacingByName('s4') 0;
354
+ @include oTypographySans($scale: 1);
355
+ &-text {
356
+ @include oTypographySans($weight: 'semibold');
357
+ color: oColorsByName('black-80');
358
+ margin-bottom: oSpacingByName('s3');
359
+ }
360
+ &-container {
361
+ margin-top: 0;
362
+ max-height: 92px;
363
+ padding: 4px 2px;
364
+ overflow-y: auto;
365
+ @include oGridRespondTo($from: M) {
366
+ max-height: 126px;
363
367
  }
364
368
  }
365
369
  }
370
+ }
366
371
 
372
+ .share-nav {
373
+ &.data-overlap-initialised {
374
+ .o-overlay {
375
+ transition: opacity 0.15s ease-in;
376
+ opacity: 0;
377
+ z-index: -1;
378
+ }
379
+ }
367
380
  .myft-notification {
368
381
  background: oColorsByName('white-80');
369
382
  box-sizing: border-box;
@@ -14,7 +14,7 @@ let scrolledOnOpen;
14
14
  let listOverlayBottom;
15
15
 
16
16
  export default async function openSaveArticleToListVariant (contentId, options = {}) {
17
- const { name, showPublicToggle = false } = options;
17
+ const { name, showPublicToggle = false, modal = false } = options;
18
18
 
19
19
  function createList (newList, cb) {
20
20
  if(!newList || !newList.name) {
@@ -81,9 +81,9 @@ export default async function openSaveArticleToListVariant (contentId, options =
81
81
  const [listElement, refreshListElement, hideListElement, showListElement] = ListsElement(lists, addToList, removeFromList);
82
82
 
83
83
  createListOverlay = new Overlay(name, {
84
+ modal,
84
85
  html: contentElement,
85
86
  heading: { title: headingElement.outerHTML },
86
- modal: false,
87
87
  parentnode: isMobile() ? '.o-share--horizontal' : '.o-share--vertical',
88
88
  class: 'myft-ui-create-list-variant',
89
89
  });
@@ -112,7 +112,7 @@ export default async function openSaveArticleToListVariant (contentId, options =
112
112
 
113
113
  function openFormHandler () {
114
114
  hideListElement();
115
- const formElement = FormElement(createList, showPublicToggle, attachDescription, onFormListCreated, onFormCancel);
115
+ const formElement = FormElement(createList, showPublicToggle, attachDescription, onFormListCreated, onFormCancel, modal);
116
116
  const overlayContent = document.querySelector('.o-overlay__content');
117
117
  removeDescription();
118
118
  overlayContent.insertAdjacentElement('beforeend', formElement);
@@ -130,17 +130,20 @@ export default async function openSaveArticleToListVariant (contentId, options =
130
130
  overlayContent.insertAdjacentElement('afterbegin', listElement);
131
131
  }
132
132
 
133
- positionOverlay(data.currentTarget);
133
+ if (!modal) {
134
+ positionOverlay(data.currentTarget);
135
+
136
+ window.addEventListener('oViewport.resize', resizeHandler);
137
+ window.addEventListener('scroll', scrollHandler);
138
+ }
134
139
 
135
140
  listOverlayBottom = document.querySelector('.myft-ui-create-list-variant').getBoundingClientRect().bottom;
136
141
 
137
142
  restoreFormHandler();
138
143
 
139
- document.querySelector('.article-content').addEventListener('click', outsideClickHandler);
144
+ document.body.addEventListener('click', outsideClickHandler);
140
145
 
141
- window.addEventListener('scroll', scrollHandler);
142
146
 
143
- window.addEventListener('oViewport.resize', resizeHandler);
144
147
  });
145
148
 
146
149
  createListOverlay.wrapper.addEventListener('oOverlay.destroy', () => {
@@ -148,7 +151,7 @@ export default async function openSaveArticleToListVariant (contentId, options =
148
151
 
149
152
  window.removeEventListener('oViewport.resize', resizeHandler);
150
153
 
151
- document.querySelector('.article-content').removeEventListener('click', outsideClickHandler);
154
+ document.body.removeEventListener('click', outsideClickHandler);
152
155
  });
153
156
  }
154
157
 
@@ -162,7 +165,7 @@ function getResizeHandler (target) {
162
165
  };
163
166
  }
164
167
 
165
- function FormElement (createList, showPublicToggle, attachDescription, onListCreated, onCancel) {
168
+ function FormElement (createList, showPublicToggle, attachDescription, onListCreated, onCancel, modal=false) {
166
169
  const formString = `
167
170
  <form class="myft-ui-create-list-variant-form">
168
171
  <label class="myft-ui-create-list-variant-form-name o-forms-field">
@@ -218,7 +221,9 @@ function FormElement (createList, showPublicToggle, attachDescription, onListCre
218
221
  createList(newList, ((contentId, createdList) => {
219
222
  triggerCreateListEvent(contentId, createdList.uuid);
220
223
  triggerAddToListEvent(contentId, createdList.uuid);
221
- positionOverlay(createListOverlay.wrapper);
224
+ if (!modal) {
225
+ positionOverlay(createListOverlay.wrapper);
226
+ }
222
227
  onListCreated();
223
228
  }));
224
229
  formElement.remove();
@@ -262,6 +267,11 @@ function ContentElement (hasDescription, onClick) {
262
267
  ${hasDescription ? `
263
268
  ${description}
264
269
  ` : ''}
270
+ <span
271
+ class="myft-ui-create-list-variant-announcement o-normalise-visually-hidden"
272
+ role="region"
273
+ aria-live="assertive"
274
+ />
265
275
  </div>
266
276
  `;
267
277
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/n-myft-ui",
3
- "version": "28.3.3",
3
+ "version": "29.0.0",
4
4
  "description": "Client side component for interaction with myft",
5
5
  "main": "server.js",
6
6
  "scripts": {