@ons/design-system 72.10.5 → 72.10.7

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.
Files changed (57) hide show
  1. package/components/button/_button.scss +8 -6
  2. package/components/char-check-limit/_macro.njk +5 -4
  3. package/components/char-check-limit/_macro.spec.js +167 -7
  4. package/components/char-check-limit/character-check.js +23 -17
  5. package/components/char-check-limit/character-check.spec.js +106 -1
  6. package/components/chart/_chart.scss +33 -5
  7. package/components/chart/_macro.njk +172 -140
  8. package/components/chart/_macro.spec.js +378 -22
  9. package/components/chart/annotations-options.js +1 -1
  10. package/components/chart/bar-chart.js +1 -0
  11. package/components/chart/chart-iframe-resize.dom.js +8 -0
  12. package/components/chart/chart-iframe-resize.js +16 -0
  13. package/components/chart/chart.js +5 -0
  14. package/components/chart/example-area-chart-with-axis-min-and-max-values.njk +72 -0
  15. package/components/chart/example-bar-chart-with-axis-min-and-max-values.njk +59 -0
  16. package/components/chart/example-bar-chart.njk +4 -0
  17. package/components/chart/example-column-chart-with-axis-min-and-max-values.njk +59 -0
  18. package/components/chart/example-iframe-chart.njk +32 -0
  19. package/components/chart/example-line-chart-with-annotations.njk +3 -1
  20. package/components/chart/example-line-chart-with-axis-min-and-max-values.njk +227 -0
  21. package/components/chart/example-line-chart.njk +4 -0
  22. package/components/chart/example-scatter-chart-with-axis-min-and-max-values.njk +98 -0
  23. package/components/chart/example-scatter-chart.njk +4 -0
  24. package/components/chart/range-annotations-options.js +1 -1
  25. package/components/chart/reference-line-annotations-options.js +1 -1
  26. package/components/chart/specific-chart-options.js +19 -0
  27. package/components/checkboxes/_macro.spec.js +3 -3
  28. package/components/details-panel/_details-panel.scss +4 -0
  29. package/components/details-panel/_macro.njk +17 -13
  30. package/components/details-panel/_macro.spec.js +17 -0
  31. package/components/details-panel/example-details-panel-open.njk +2 -1
  32. package/components/details-panel/example-details-panel.njk +2 -1
  33. package/components/header/_header.scss +40 -24
  34. package/components/header/_macro.njk +103 -89
  35. package/components/header/_macro.spec.js +130 -2
  36. package/components/header/example-header-basic-with-search-and-language.njk +207 -0
  37. package/components/header/{example-header-with-search-button.njk → example-header-basic-with-search-button.njk} +1 -0
  38. package/components/header/example-header-basic.njk +1 -0
  39. package/components/hero/_macro.njk +9 -2
  40. package/components/hero/_macro.spec.js +22 -0
  41. package/components/hero/example-hero-grey.njk +2 -1
  42. package/components/input/_macro.njk +1 -2
  43. package/components/input/_macro.spec.js +2 -22
  44. package/components/input/example-input-search-with-character-check.njk +0 -1
  45. package/components/language-selector/_macro.njk +1 -1
  46. package/components/language-selector/_macro.spec.js +45 -0
  47. package/components/navigation/navigation.js +24 -17
  48. package/components/pagination/_macro.njk +17 -7
  49. package/components/pagination/_macro.spec.js +191 -17
  50. package/components/textarea/_macro.njk +19 -3
  51. package/components/textarea/_macro.spec.js +76 -3
  52. package/components/textarea/example-textarea-with-word-limit.njk +20 -0
  53. package/css/main.css +1 -1
  54. package/js/main.js +2 -0
  55. package/package.json +3 -2
  56. package/scripts/main.es5.js +3 -1
  57. package/scripts/main.js +3 -1
@@ -105,7 +105,7 @@ describe('macro: pagination', () => {
105
105
  expect($('li').length).toBe(3);
106
106
  assertIsCurrentPage($('.ons-pagination__item:nth-child(1)'), '/page/1', 'Current page (Page 1 of 2)', '1');
107
107
  assertIsNextPage($('.ons-pagination__item:nth-child(2)'), '/page/2', 'Go to page 2', '2');
108
- assertIsNextPage($('.ons-pagination__item:nth-child(3)'), '/page/2', 'Go to the next page (Page 2)', 'Next page');
108
+ assertIsNextPage($('.ons-pagination__item:nth-child(3)'), '/page/2', 'Go to the next page (2)', 'Next page');
109
109
  });
110
110
  });
111
111
 
@@ -133,7 +133,7 @@ describe('macro: pagination', () => {
133
133
 
134
134
  it('has a 3 list items ("Previous page", "1", "2")', () => {
135
135
  expect($('li').length).toBe(3);
136
- assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/1', 'Go to the previous page (Page 1)', 'Previous page');
136
+ assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/1', 'Go to the previous page (1)', 'Previous page');
137
137
  assertIsPreviousPage($('.ons-pagination__item:nth-child(2)'), '/page/1', 'Go to page 1', '1');
138
138
  assertIsCurrentPage($('.ons-pagination__item:nth-child(3)'), '/page/2', 'Current page (Page 2 of 2)', '2');
139
139
  });
@@ -163,11 +163,11 @@ describe('macro: pagination', () => {
163
163
 
164
164
  it('has a 5 list items ("Previous page", "1", "2", "3", "Next page")', () => {
165
165
  expect($('li').length).toBe(5);
166
- assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/1', 'Go to the previous page (Page 1)', 'Previous page');
166
+ assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/1', 'Go to the previous page (1)', 'Previous page');
167
167
  assertIsPreviousPage($('.ons-pagination__item:nth-child(2)'), '/page/1', 'Go to page 1', '1');
168
168
  assertIsCurrentPage($('.ons-pagination__item:nth-child(3)'), '/page/2', 'Current page (Page 2 of 3)', '2');
169
169
  assertIsNextPage($('.ons-pagination__item:nth-child(4)'), '/page/3', 'Go to page 3', '3');
170
- assertIsNextPage($('.ons-pagination__item:nth-child(5)'), '/page/3', 'Go to the next page (Page 3)', 'Next page');
170
+ assertIsNextPage($('.ons-pagination__item:nth-child(5)'), '/page/3', 'Go to the next page (3)', 'Next page');
171
171
  });
172
172
  });
173
173
 
@@ -195,13 +195,13 @@ describe('macro: pagination', () => {
195
195
 
196
196
  it('has a 7 list items ("Previous page", "1", "2", "3", "4", "5", "Next page")', () => {
197
197
  expect($('li').length).toBe(7);
198
- assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/1', 'Go to the previous page (Page 1)', 'Previous page');
198
+ assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/1', 'Go to the previous page (1)', 'Previous page');
199
199
  assertIsPreviousPage($('.ons-pagination__item:nth-child(2)'), '/page/1', 'Go to page 1', '1');
200
200
  assertIsCurrentPage($('.ons-pagination__item:nth-child(3)'), '/page/2', 'Current page (Page 2 of 5)', '2');
201
201
  assertIsNextPage($('.ons-pagination__item:nth-child(4)'), '/page/3', 'Go to page 3', '3');
202
202
  assertIsOtherPage($('.ons-pagination__item:nth-child(5)'), '/page/4', 'Go to page 4', '4');
203
- assertIsOtherPage($('.ons-pagination__item:nth-child(6)'), '/page/5', 'Go to the last page (Page 5)', '5');
204
- assertIsNextPage($('.ons-pagination__item:nth-child(7)'), '/page/3', 'Go to the next page (Page 3)', 'Next page');
203
+ assertIsOtherPage($('.ons-pagination__item:nth-child(6)'), '/page/5', 'Go to the last page (5)', '5');
204
+ assertIsNextPage($('.ons-pagination__item:nth-child(7)'), '/page/3', 'Go to the next page (3)', 'Next page');
205
205
  });
206
206
  });
207
207
 
@@ -236,13 +236,13 @@ describe('macro: pagination', () => {
236
236
 
237
237
  it('has 7 list items ("Previous page", "1", "2", "3", "...", "6", "Next page")', () => {
238
238
  expect($('li').length).toBe(7);
239
- assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/1', 'Go to the previous page (Page 1)', 'Previous page');
239
+ assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/1', 'Go to the previous page (1)', 'Previous page');
240
240
  assertIsPreviousPage($('.ons-pagination__item:nth-child(2)'), '/page/1', 'Go to page 1', '1');
241
241
  assertIsCurrentPage($('.ons-pagination__item:nth-child(3)'), '/page/2', 'Current page (Page 2 of 6)', '2');
242
242
  assertIsNextPage($('.ons-pagination__item:nth-child(4)'), '/page/3', 'Go to page 3', '3');
243
243
  assertIsGap($('.ons-pagination__item:nth-child(5)'));
244
- assertIsOtherPage($('.ons-pagination__item:nth-child(6)'), '/page/6', 'Go to the last page (Page 6)', '6');
245
- assertIsNextPage($('.ons-pagination__item:nth-child(7)'), '/page/3', 'Go to the next page (Page 3)', 'Next page');
244
+ assertIsOtherPage($('.ons-pagination__item:nth-child(6)'), '/page/6', 'Go to the last page (6)', '6');
245
+ assertIsNextPage($('.ons-pagination__item:nth-child(7)'), '/page/3', 'Go to the next page (3)', 'Next page');
246
246
  });
247
247
  });
248
248
 
@@ -282,15 +282,15 @@ describe('macro: pagination', () => {
282
282
 
283
283
  it('has a 9 list items ("Previous page", "1", "...", "4", "5", "6", "...", "11", "Next page")', () => {
284
284
  expect($('li').length).toBe(9);
285
- assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/4', 'Go to the previous page (Page 4)', 'Previous page');
286
- assertIsOtherPage($('.ons-pagination__item:nth-child(2)'), '/page/1', 'Go to the first page (Page 1)', '1');
285
+ assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/4', 'Go to the previous page (4)', 'Previous page');
286
+ assertIsOtherPage($('.ons-pagination__item:nth-child(2)'), '/page/1', 'Go to the first page', '1');
287
287
  assertIsGap($('.ons-pagination__item:nth-child(3)'));
288
288
  assertIsPreviousPage($('.ons-pagination__item:nth-child(4)'), '/page/4', 'Go to page 4', '4');
289
289
  assertIsCurrentPage($('.ons-pagination__item:nth-child(5)'), '/page/5', 'Current page (Page 5 of 11)', '5');
290
290
  assertIsNextPage($('.ons-pagination__item:nth-child(6)'), '/page/6', 'Go to page 6', '6');
291
291
  assertIsGap($('.ons-pagination__item:nth-child(7)'));
292
- assertIsOtherPage($('.ons-pagination__item:nth-child(8)'), '/page/11', 'Go to the last page (Page 11)', '11');
293
- assertIsNextPage($('.ons-pagination__item:nth-child(9)'), '/page/6', 'Go to the next page (Page 6)', 'Next page');
292
+ assertIsOtherPage($('.ons-pagination__item:nth-child(8)'), '/page/11', 'Go to the last page (11)', '11');
293
+ assertIsNextPage($('.ons-pagination__item:nth-child(9)'), '/page/6', 'Go to the next page (6)', 'Next page');
294
294
  });
295
295
  });
296
296
 
@@ -330,13 +330,187 @@ describe('macro: pagination', () => {
330
330
 
331
331
  it('has a 7 list items ("Previous page", "1", "...", "9", "10", "11", "Next page")', () => {
332
332
  expect($('li').length).toBe(7);
333
- assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/9', 'Go to the previous page (Page 9)', 'Previous page');
334
- assertIsOtherPage($('.ons-pagination__item:nth-child(2)'), '/page/1', 'Go to the first page (Page 1)', '1');
333
+ assertIsPreviousPage($('.ons-pagination__item:nth-child(1)'), '/page/9', 'Go to the previous page (9)', 'Previous page');
334
+ assertIsOtherPage($('.ons-pagination__item:nth-child(2)'), '/page/1', 'Go to the first page', '1');
335
335
  assertIsGap($('.ons-pagination__item:nth-child(3)'));
336
336
  assertIsPreviousPage($('.ons-pagination__item:nth-child(4)'), '/page/9', 'Go to page 9', '9');
337
337
  assertIsCurrentPage($('.ons-pagination__item:nth-child(5)'), '/page/10', 'Current page (Page 10 of 11)', '10');
338
338
  assertIsNextPage($('.ons-pagination__item:nth-child(6)'), '/page/11', 'Go to page 11', '11');
339
- assertIsNextPage($('.ons-pagination__item:nth-child(7)'), '/page/11', 'Go to the next page (Page 11)', 'Next page');
339
+ assertIsNextPage($('.ons-pagination__item:nth-child(7)'), '/page/11', 'Go to the next page (11)', 'Next page');
340
+ });
341
+ });
342
+
343
+ describe('custom previousAriaLabel and nextAriaLabel', () => {
344
+ const customPreviousAriaLabel = 'Go back to page';
345
+ const customNextAriaLabel = 'Continue to page';
346
+ const $custom = cheerio.load(
347
+ renderComponent('pagination', {
348
+ currentPageNumber: 2,
349
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }],
350
+ previous: 'Previous',
351
+ next: 'Next',
352
+ previousAriaLabel: customPreviousAriaLabel,
353
+ nextAriaLabel: customNextAriaLabel,
354
+ }),
355
+ );
356
+ const $default = cheerio.load(
357
+ renderComponent('pagination', {
358
+ currentPageNumber: 2,
359
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }],
360
+ previous: 'Previous',
361
+ next: 'Next',
362
+ }),
363
+ );
364
+
365
+ it('renders the custom previousAriaLabel and page number on the Previous link', () => {
366
+ const prevItem = $custom('.ons-pagination__item--previous');
367
+ expect(prevItem.length).toBe(1);
368
+ expect(prevItem.find('a').attr('aria-label')).toBe('Go back to page (1)');
369
+ });
370
+ it('renders the default previousAriaLabel and page number on the Previous link if not provided', () => {
371
+ const prevItem = $default('.ons-pagination__item--previous');
372
+ expect(prevItem.length).toBe(1);
373
+ expect(prevItem.find('a').attr('aria-label')).toBe('Go to the previous page (1)');
374
+ });
375
+ it('renders the custom nextAriaLabel and page number on the Next link', () => {
376
+ const nextItem = $custom('.ons-pagination__item--next');
377
+ expect(nextItem.length).toBe(1);
378
+ expect(nextItem.find('a').attr('aria-label')).toBe('Continue to page (3)');
379
+ });
380
+ it('renders the default nextAriaLabel and page number on the Next link if not provided', () => {
381
+ const nextItem = $default('.ons-pagination__item--next');
382
+ expect(nextItem.length).toBe(1);
383
+ expect(nextItem.find('a').attr('aria-label')).toBe('Go to the next page (3)');
384
+ });
385
+ });
386
+
387
+ describe('custom ariaLabel', () => {
388
+ it('renders a custom aria-label on the nav element', () => {
389
+ const $ = cheerio.load(
390
+ renderComponent('pagination', {
391
+ currentPageNumber: 2,
392
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }],
393
+ ariaLabel: 'Custom pagination navigation',
394
+ }),
395
+ );
396
+ expect($('.ons-pagination').attr('aria-label')).toBe('Custom pagination navigation (Page 2 of 3)');
397
+ });
398
+ it('renders the default aria-label on the nav element if not provided', () => {
399
+ const $ = cheerio.load(
400
+ renderComponent('pagination', {
401
+ currentPageNumber: 2,
402
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }],
403
+ }),
404
+ );
405
+ expect($('.ons-pagination').attr('aria-label')).toBe('Pagination (Page 2 of 3)');
406
+ });
407
+ });
408
+
409
+ describe('custom firstAriaLabel', () => {
410
+ it('renders a custom aria-label on the first page link', () => {
411
+ const $ = cheerio.load(
412
+ renderComponent('pagination', {
413
+ currentPageNumber: 3,
414
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }, { url: '/page/4' }],
415
+ firstAriaLabel: 'Jump to first page',
416
+ }),
417
+ );
418
+ const firstPageLink = $('.ons-pagination__item a').filter(function () {
419
+ return $(this).text().trim() === '1';
420
+ });
421
+ expect(firstPageLink.attr('aria-label')).toBe('Jump to first page');
422
+ });
423
+ it('renders the default aria-label on the first page link if not provided', () => {
424
+ const $ = cheerio.load(
425
+ renderComponent('pagination', {
426
+ currentPageNumber: 3,
427
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }, { url: '/page/4' }],
428
+ }),
429
+ );
430
+ const firstPageLink = $('.ons-pagination__item a').filter(function () {
431
+ return $(this).text().trim() === '1';
432
+ });
433
+ expect(firstPageLink.attr('aria-label')).toBe('Go to the first page');
434
+ });
435
+ });
436
+
437
+ describe('custom currentAriaLabel', () => {
438
+ it('renders a custom aria-label on the current page link', () => {
439
+ const $ = cheerio.load(
440
+ renderComponent('pagination', {
441
+ currentPageNumber: 2,
442
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }],
443
+ currentAriaLabel: 'You are on page',
444
+ }),
445
+ );
446
+ const currentPageLink = $('.ons-pagination__item--current a');
447
+ expect(currentPageLink.attr('aria-label')).toBe('You are on page (Page 2 of 3)');
448
+ });
449
+ it('renders the default aria-label on the current page link if not provided', () => {
450
+ const $ = cheerio.load(
451
+ renderComponent('pagination', {
452
+ currentPageNumber: 2,
453
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }],
454
+ }),
455
+ );
456
+ const currentPageLink = $('.ons-pagination__item--current a');
457
+ expect(currentPageLink.attr('aria-label')).toBe('Current page (Page 2 of 3)');
458
+ });
459
+ });
460
+
461
+ describe('custom lastAriaLabel', () => {
462
+ it('renders a custom aria-label on the last page link', () => {
463
+ const $ = cheerio.load(
464
+ renderComponent('pagination', {
465
+ currentPageNumber: 2,
466
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }, { url: '/page/4' }],
467
+ lastAriaLabel: 'Jump to last page',
468
+ }),
469
+ );
470
+ const lastPageLink = $('.ons-pagination__item a').filter(function () {
471
+ return $(this).text().trim() === '4';
472
+ });
473
+ expect(lastPageLink.attr('aria-label')).toBe('Jump to last page (4)');
474
+ });
475
+ it('renders the default aria-label on the last page link if not provided', () => {
476
+ const $ = cheerio.load(
477
+ renderComponent('pagination', {
478
+ currentPageNumber: 2,
479
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }, { url: '/page/4' }],
480
+ }),
481
+ );
482
+ const lastPageLink = $('.ons-pagination__item a').filter(function () {
483
+ return $(this).text().trim() === '4';
484
+ });
485
+ expect(lastPageLink.attr('aria-label')).toBe('Go to the last page (4)');
486
+ });
487
+ });
488
+
489
+ describe('custom goToAriaLabel', () => {
490
+ it('renders a custom aria-label on non-current, non-first/last page links', () => {
491
+ const $ = cheerio.load(
492
+ renderComponent('pagination', {
493
+ currentPageNumber: 3,
494
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }, { url: '/page/4' }, { url: '/page/5' }],
495
+ goToAriaLabel: 'Jump to page',
496
+ }),
497
+ );
498
+ const page2Link = $('.ons-pagination__item a').filter(function () {
499
+ return $(this).text().trim() === '2';
500
+ });
501
+ expect(page2Link.attr('aria-label')).toBe('Jump to page 2');
502
+ });
503
+ it('renders the default aria-label on non-current, non-first/last page links if not provided', () => {
504
+ const $ = cheerio.load(
505
+ renderComponent('pagination', {
506
+ currentPageNumber: 3,
507
+ pages: [{ url: '/page/1' }, { url: '/page/2' }, { url: '/page/3' }, { url: '/page/4' }, { url: '/page/5' }],
508
+ }),
509
+ );
510
+ const page2Link = $('.ons-pagination__item a').filter(function () {
511
+ return $(this).text().trim() === '2';
512
+ });
513
+ expect(page2Link.attr('aria-label')).toBe('Go to page 2');
340
514
  });
341
515
  });
342
516
  });
@@ -19,14 +19,17 @@
19
19
 
20
20
  <textarea
21
21
  id="{{ params.id }}"
22
- class="ons-input ons-input--textarea{{ ' ons-input--error' if params.error }}{{ ' ons-js-char-check-input' if params.charCheckLimit and params.charCheckLimit.limit }}{{ textareaExclusiveClass }}{{ ' ' + params.classes if params.classes else '' }}{% if params.width %}{{ ' ' }}ons-input--w-{{ params.width }}{% endif %}"
22
+ class="ons-input ons-input--textarea{{ ' ons-input--error' if params.error }}{{ ' ons-js-char-check-input' if (params.charCheckLimit and params.charCheckLimit.limit) or (params.wordCheckLimit and params.wordCheckLimit.limit) }}{{ textareaExclusiveClass }}{{ ' ' + params.classes if params.classes else '' }}{% if params.width %}{{ ' ' }}ons-input--w-{{ params.width }}{% endif %}"
23
23
  {% if params.name %}
24
24
  name="{{ params.name }}"
25
25
  {% endif %}
26
26
  rows="{{ params.rows | default(8) }}"
27
27
  {% if params.charCheckLimit %}
28
- data-char-check-ref="{{ params.id }}-check" data-char-check-num="{{ params.charCheckLimit.limit }}"
29
- aria-describedby="{{ params.id }}-check" data-char-check-countdown=true
28
+ data-message-check-ref="{{ params.id }}-check" data-message-check-num="{{ params.charCheckLimit.limit }}"
29
+ aria-describedby="{{ params.id }}-check"
30
+ {% elif params.wordCheckLimit %}
31
+ data-message-check-ref="{{ params.id }}-check" data-message-check-num="{{ params.wordCheckLimit.limit }}"
32
+ aria-describedby="{{ params.id }}-check"
30
33
  {% endif %}
31
34
  {% if params.attributes %}{% for attribute, value in (params.attributes.items() if params.attributes is mapping and params.attributes.items else params.attributes) %}{{ ' ' }}{{ attribute }}{% if value %}="{{ value }}"{% endif %}{% endfor %}{% endif %}
32
35
  >
@@ -45,6 +48,19 @@
45
48
  })
46
49
  %}
47
50
  {% endcall %}
51
+ {% elif params.wordCheckLimit and params.wordCheckLimit.limit %}
52
+ {%
53
+ call onsCharLimit({
54
+ "id": params.id ~ "-check",
55
+ "variant": "word",
56
+ "limit": params.wordCheckLimit.limit,
57
+ "wordCountSingular": params.wordCheckLimit.wordCountSingular,
58
+ "wordCountPlural": params.wordCheckLimit.wordCountPlural,
59
+ "wordCountOverLimitSingular": params.wordCheckLimit.wordCountOverLimitSingular,
60
+ "wordCountOverLimitPlural": params.wordCheckLimit.wordCountOverLimitPlural
61
+ })
62
+ %}
63
+ {% endcall %}
48
64
  {% endif %}
49
65
  {% endset %}
50
66
 
@@ -27,6 +27,17 @@ const EXAMPLE_TEXTAREA_WITH_CHARACTER_LIMIT = {
27
27
  },
28
28
  };
29
29
 
30
+ const EXAMPLE_TEXTAREA_WITH_WORD_LIMIT = {
31
+ ...EXAMPLE_TEXTAREA,
32
+ width: 30,
33
+ wordCheckLimit: {
34
+ limit: 5,
35
+ wordCountSingular: 'You have {x} word remaining',
36
+ wordCountPlural: 'You have {x} words remaining',
37
+ wordCountOverLimitSingular: '{x} word too many',
38
+ wordCountOverLimitPlural: '{x} words too many',
39
+ },
40
+ };
30
41
  const EXAMPLE_TEXTAREA_WITH_ERROR = {
31
42
  ...EXAMPLE_TEXTAREA,
32
43
  error: {
@@ -212,13 +223,13 @@ describe('macro: textarea', () => {
212
223
  it('has the provided maximum length', () => {
213
224
  const $ = cheerio.load(renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_CHARACTER_LIMIT));
214
225
 
215
- expect($('.ons-input--textarea').attr('data-char-check-num')).toBe('200');
226
+ expect($('.ons-input--textarea').attr('data-message-check-num')).toBe('200');
216
227
  });
217
228
 
218
229
  it('has data attribute which references the character check component', () => {
219
230
  const $ = cheerio.load(renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_CHARACTER_LIMIT));
220
231
 
221
- expect($('.ons-input--textarea').attr('data-char-check-ref')).toBe('example-id-check');
232
+ expect($('.ons-input--textarea').attr('data-message-check-ref')).toBe('example-id-check');
222
233
  });
223
234
 
224
235
  it('has `aria-describedby` attribute which references the character limit component', () => {
@@ -227,7 +238,7 @@ describe('macro: textarea', () => {
227
238
  expect($('.ons-input--textarea').attr('aria-describedby')).toBe('example-id-check');
228
239
  });
229
240
 
230
- it('renders character limit component', () => {
241
+ it('renders character check limit component', () => {
231
242
  const faker = templateFaker();
232
243
  const charCheckLimitSpy = faker.spy('char-check-limit');
233
244
 
@@ -244,6 +255,68 @@ describe('macro: textarea', () => {
244
255
  });
245
256
  });
246
257
 
258
+ describe('with word check', () => {
259
+ it('has the `ons-js-char-check-input` class', () => {
260
+ const $ = cheerio.load(renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_WORD_LIMIT));
261
+
262
+ expect($('.ons-input--textarea').hasClass('ons-js-char-check-input')).toBe(true);
263
+ });
264
+
265
+ it('has the provided maximum length', () => {
266
+ const $ = cheerio.load(renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_WORD_LIMIT));
267
+
268
+ expect($('.ons-input--textarea').attr('data-message-check-num')).toBe('5');
269
+ });
270
+
271
+ it('has data attribute which references the word check component', () => {
272
+ const $ = cheerio.load(renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_WORD_LIMIT));
273
+
274
+ expect($('.ons-input--textarea').attr('data-message-check-ref')).toBe('example-id-check');
275
+ });
276
+
277
+ it('has `aria-describedby` attribute which references the word limit component', () => {
278
+ const $ = cheerio.load(renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_WORD_LIMIT));
279
+
280
+ expect($('.ons-input--textarea').attr('aria-describedby')).toBe('example-id-check');
281
+ });
282
+
283
+ it('renders char check limit component which counts words instead of characters', () => {
284
+ const faker = templateFaker();
285
+ const charCheckLimitSpy = faker.spy('char-check-limit');
286
+
287
+ faker.renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_WORD_LIMIT);
288
+
289
+ expect(charCheckLimitSpy.occurrences).toContainEqual({
290
+ id: 'example-id-check',
291
+ limit: 5,
292
+ variant: 'word',
293
+ wordCountSingular: 'You have {x} word remaining',
294
+ wordCountPlural: 'You have {x} words remaining',
295
+ wordCountOverLimitSingular: '{x} word too many',
296
+ wordCountOverLimitPlural: '{x} words too many',
297
+ });
298
+ });
299
+ });
300
+
301
+ describe('with character check and word check', () => {
302
+ it('only renders char check limit component which counts characters', () => {
303
+ const faker = templateFaker();
304
+ const charCheckLimitSpy = faker.spy('char-check-limit');
305
+
306
+ faker.renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_WORD_LIMIT);
307
+
308
+ expect(charCheckLimitSpy.occurrences).toContainEqual({
309
+ id: 'example-id-check',
310
+ limit: 5,
311
+ variant: 'word',
312
+ wordCountSingular: 'You have {x} word remaining',
313
+ wordCountPlural: 'You have {x} words remaining',
314
+ wordCountOverLimitSingular: '{x} word too many',
315
+ wordCountOverLimitPlural: '{x} words too many',
316
+ });
317
+ });
318
+ });
319
+
247
320
  describe('with error', () => {
248
321
  it('has the `error` modifier class', () => {
249
322
  const $ = cheerio.load(renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_ERROR));
@@ -0,0 +1,20 @@
1
+ {% from "components/textarea/_macro.njk" import onsTextarea %}
2
+
3
+ {{
4
+ onsTextarea({
5
+ "id": "textarea-word-limit",
6
+ "name": "feedback-limited",
7
+ "width": "30",
8
+ "label": {
9
+ "text": "Please provide some feedback",
10
+ "description": "For example, describe any difficulties you experienced in the use of this service"
11
+ },
12
+ "wordCheckLimit": {
13
+ "limit": 150,
14
+ "wordCountSingular": "You have {x} word remaining",
15
+ "wordCountPlural": "You have {x} words remaining",
16
+ "wordCountOverLimitSingular": "You are {x} word over the limit",
17
+ "wordCountOverLimitPlural": "You are {x} words over the limit"
18
+ }
19
+ })
20
+ }}