@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
@@ -25,6 +25,7 @@ import {
25
25
  EXAMPLE_LINE_CHART_WITH_RANGE_ANNOTATION_WITH_LABEL_INSIDE_PARAMS,
26
26
  EXAMPLE_LINE_CHART_WITH_REFERENCE_LINE_ANNOTATIONS_PARAMS,
27
27
  EXAMPLE_LINE_CHART_WITH_MIXED_ANNOTATION_TYPES_PARAMS,
28
+ EXAMPLE_IFRAME_CHART_PARAMS,
28
29
  } from './_test-examples';
29
30
 
30
31
  describe('Macro: Chart', () => {
@@ -207,6 +208,30 @@ describe('Macro: Chart', () => {
207
208
  });
208
209
  });
209
210
 
211
+ describe('GIVEN: Params: unsupportedChartText', () => {
212
+ describe('WHEN: unsupportedChartText is provided', () => {
213
+ const params = { ...EXAMPLE_INVALID_CHART_PARAMS, unsupportedChartText: 'this chart type is not valid' };
214
+ const $ = cheerio.load(renderComponent('chart', params));
215
+
216
+ test('THEN: it renders the unsupported chart text in the correct element', () => {
217
+ const invalid = $('[data-invalid-chart-type]');
218
+ expect(invalid.length).toBe(1);
219
+ expect(invalid.text().trim()).toContain('- this chart type is not valid');
220
+ });
221
+ });
222
+
223
+ describe('WHEN: unsupportedChartText is not provided', () => {
224
+ const params = { ...EXAMPLE_INVALID_CHART_PARAMS };
225
+ const $ = cheerio.load(renderComponent('chart', params));
226
+
227
+ test('THEN: it renders the default unsupported chart text', () => {
228
+ const invalid = $('[data-invalid-chart-type]');
229
+ expect(invalid.length).toBe(1);
230
+ expect(invalid.text().trim()).toBe('"invalid" - chart type is not supported');
231
+ });
232
+ });
233
+ });
234
+
210
235
  describe('GIVEN: Params: Description', () => {
211
236
  describe('WHEN: description is provided', () => {
212
237
  const $ = cheerio.load(
@@ -604,14 +629,14 @@ describe('Macro: Chart', () => {
604
629
  });
605
630
 
606
631
  test('THEN: it renders the footnotes', () => {
607
- expect($('.ons-chart__footnotes').text()).toContain('1');
608
- expect($('.ons-chart__footnotes').text()).toContain('A test annotation');
609
- expect($('.ons-chart__footnotes').text()).toContain('2');
610
- expect($('.ons-chart__footnotes').text()).toContain('Another test annotation');
632
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('1');
633
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('A test annotation');
634
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('2');
635
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('Another test annotation');
611
636
  });
612
637
 
613
638
  test('THEN: the footnotes are hidden from screen readers', () => {
614
- expect($('.ons-chart__footnotes').attr('aria-hidden')).toBe('true');
639
+ expect($('.ons-chart__annotations-footnotes').attr('aria-hidden')).toBe('true');
615
640
  });
616
641
 
617
642
  test('THEN: it includes the Annotations JSON config', () => {
@@ -634,12 +659,12 @@ describe('Macro: Chart', () => {
634
659
  });
635
660
 
636
661
  test('THEN: it renders the footnotes', () => {
637
- expect($('.ons-chart__footnotes').text()).toContain('1');
638
- expect($('.ons-chart__footnotes').text()).toContain('A test annotation');
662
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('1');
663
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('A test annotation');
639
664
  });
640
665
 
641
666
  test('THEN: the footnotes are hidden from screen readers', () => {
642
- expect($('.ons-chart__footnotes').attr('aria-hidden')).toBe('true');
667
+ expect($('.ons-chart__annotations-footnotes').attr('aria-hidden')).toBe('true');
643
668
  });
644
669
 
645
670
  test('THEN: it includes the Annotations JSON config', () => {
@@ -663,12 +688,12 @@ describe('Macro: Chart', () => {
663
688
  });
664
689
 
665
690
  test('THEN: it renders the footnotes', () => {
666
- expect($('.ons-chart__footnotes').text()).toContain('1');
667
- expect($('.ons-chart__footnotes').text()).toContain('A test annotation');
691
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('1');
692
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('A test annotation');
668
693
  });
669
694
 
670
695
  test('THEN: the footnotes are hidden from screen readers', () => {
671
- expect($('.ons-chart__footnotes').attr('aria-hidden')).toBe('true');
696
+ expect($('.ons-chart__annotations-footnotes').attr('aria-hidden')).toBe('true');
672
697
  });
673
698
 
674
699
  test('THEN: it includes the Annotations JSON config', () => {
@@ -953,6 +978,26 @@ describe('Macro: Chart', () => {
953
978
  });
954
979
  });
955
980
  });
981
+
982
+ describe('GIVEN: Params: Footnotes', () => {
983
+ describe('WHEN: footnotes are provided', () => {
984
+ const $ = cheerio.load(
985
+ renderComponent('chart', {
986
+ ...EXAMPLE_AREA_CHART_PARAMS,
987
+ footnotes: {
988
+ title: 'Footnotes',
989
+ content:
990
+ '<ol><li>Non-store retailing refers to retailers that do not have a store presence. While the majority is made up of online retailers, it also includes other retailers, such as stalls and markets.</li><li>More data are available in our Retail Sales Index datasets.</li></ol>',
991
+ },
992
+ }),
993
+ );
994
+ test('THEN: it renders the footnotes', () => {
995
+ expect($('#footnotes--area-chart-123').length).toBe(1);
996
+ expect($('#footnotes--area-chart-123').find('ol').length).toBe(1);
997
+ expect($('#footnotes--area-chart-123').text()).toContain('Footnotes');
998
+ });
999
+ });
1000
+ });
956
1001
  });
957
1002
 
958
1003
  describe('FOR: Boxplot Chart', () => {
@@ -1146,7 +1191,7 @@ describe('Macro: Chart', () => {
1146
1191
  });
1147
1192
 
1148
1193
  test('THEN: it renders the error message', () => {
1149
- expect($('[data-invalid-chart-type]').text()).toBe('Chart type "invalid" is not supported');
1194
+ expect($('[data-invalid-chart-type]').text().trim()).toBe('"invalid" - chart type is not supported');
1150
1195
  });
1151
1196
 
1152
1197
  test('THEN: it does not include the Highcharts JSON config', () => {
@@ -1280,16 +1325,327 @@ describe('Macro: Chart', () => {
1280
1325
  });
1281
1326
 
1282
1327
  test('THEN: it renders the footnotes sequentially', () => {
1283
- expect($('.ons-chart__footnotes').text()).toContain('1');
1284
- expect($('.ons-chart__footnotes').text()).toContain('A test point annotation');
1285
- expect($('.ons-chart__footnotes').text()).toContain('2');
1286
- expect($('.ons-chart__footnotes').text()).toContain('A test x axis range annotation');
1287
- expect($('.ons-chart__footnotes').text()).toContain('3');
1288
- expect($('.ons-chart__footnotes').text()).toContain('A test y axis range annotation with the label inside');
1289
- expect($('.ons-chart__footnotes').text()).toContain('4');
1290
- expect($('.ons-chart__footnotes').text()).toContain('A test x axis reference line annotation');
1291
- expect($('.ons-chart__footnotes').text()).toContain('5');
1292
- expect($('.ons-chart__footnotes').text()).toContain('A test y axis reference line annotation');
1328
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('1');
1329
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('A test point annotation');
1330
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('2');
1331
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('A test x axis range annotation');
1332
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('3');
1333
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('A test y axis range annotation with the label inside');
1334
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('4');
1335
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('A test x axis reference line annotation');
1336
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('5');
1337
+ expect($('.ons-chart__annotations-footnotes').text()).toContain('A test y axis reference line annotation');
1338
+ });
1339
+ });
1340
+ });
1341
+ });
1342
+
1343
+ describe('FOR: Axis Min, Max, startOnTick, endOnTick', () => {
1344
+ const BASE_PARAMS = {
1345
+ id: 'test-chart',
1346
+ title: 'Test Chart',
1347
+ xAxis: {
1348
+ title: 'X Axis Title',
1349
+ categories: ['A', 'B', 'C'],
1350
+ type: 'linear',
1351
+ labelFormat: '{value}',
1352
+ },
1353
+ yAxis: {
1354
+ title: 'Y Axis Title',
1355
+ labelFormat: '{value}',
1356
+ },
1357
+ series: [],
1358
+ };
1359
+
1360
+ describe('GIVEN: chartType supports xAxis min/max (bar, scatter)', () => {
1361
+ test('THEN: xAxis min and max are included in config when provided', () => {
1362
+ const params = {
1363
+ ...BASE_PARAMS,
1364
+ chartType: 'scatter',
1365
+ xAxis: {
1366
+ ...BASE_PARAMS.xAxis,
1367
+ min: 1,
1368
+ max: 10,
1369
+ startOnTick: true,
1370
+ endOnTick: false,
1371
+ },
1372
+ };
1373
+
1374
+ const $ = cheerio.load(renderComponent('chart', params));
1375
+ const configScript = $(`script[data-highcharts-config--${params.id}]`).html();
1376
+
1377
+ expect(configScript).toContain('"min":1');
1378
+ expect(configScript).toContain('"max":10');
1379
+ expect(configScript).toContain('"startOnTick":true');
1380
+ expect(configScript).toContain('"endOnTick":false');
1381
+ });
1382
+
1383
+ test('THEN: xAxis min and max are NOT included if not defined', () => {
1384
+ const params = {
1385
+ ...BASE_PARAMS,
1386
+ chartType: 'scatter',
1387
+ xAxis: {
1388
+ ...BASE_PARAMS.xAxis,
1389
+ min: undefined,
1390
+ max: undefined,
1391
+ startOnTick: undefined,
1392
+ endOnTick: undefined,
1393
+ },
1394
+ };
1395
+
1396
+ const $ = cheerio.load(renderComponent('chart', params));
1397
+ const configScript = $(`script[data-highcharts-config--${params.id}]`).html();
1398
+
1399
+ const config = JSON.parse(configScript);
1400
+
1401
+ expect(config.xAxis.min).toBeUndefined();
1402
+ expect(config.xAxis.max).toBeUndefined();
1403
+ expect(config.xAxis.startOnTick).toBeUndefined();
1404
+ expect(config.xAxis.endOnTick).toBeUndefined();
1405
+ });
1406
+ });
1407
+
1408
+ describe('GIVEN: chartType supports yAxis min/max (line, bar, column, scatter, area, columnrange, boxplot)', () => {
1409
+ test('THEN: yAxis min and max are included in config when provided', () => {
1410
+ const params = {
1411
+ ...BASE_PARAMS,
1412
+ chartType: 'line',
1413
+ yAxis: {
1414
+ ...BASE_PARAMS.yAxis,
1415
+ min: 0,
1416
+ max: 100,
1417
+ startOnTick: false,
1418
+ endOnTick: true,
1419
+ },
1420
+ };
1421
+
1422
+ const $ = cheerio.load(renderComponent('chart', params));
1423
+ const configScript = $(`script[data-highcharts-config--${params.id}]`).html();
1424
+
1425
+ expect(configScript).toContain('"min":0');
1426
+ expect(configScript).toContain('"max":100');
1427
+ expect(configScript).toContain('"startOnTick":false');
1428
+ expect(configScript).toContain('"endOnTick":true');
1429
+ });
1430
+
1431
+ test('THEN: yAxis min and max are NOT included if not defined', () => {
1432
+ const params = {
1433
+ ...BASE_PARAMS,
1434
+ chartType: 'line',
1435
+ yAxis: {
1436
+ ...BASE_PARAMS.yAxis,
1437
+ min: undefined,
1438
+ max: undefined,
1439
+ startOnTick: undefined,
1440
+ endOnTick: undefined,
1441
+ },
1442
+ };
1443
+
1444
+ const $ = cheerio.load(renderComponent('chart', params));
1445
+ const configScript = $(`script[data-highcharts-config--${params.id}]`).html();
1446
+
1447
+ const config = JSON.parse(configScript);
1448
+
1449
+ expect(config.yAxis.min).toBeUndefined();
1450
+ expect(config.yAxis.max).toBeUndefined();
1451
+ expect(config.yAxis.startOnTick).toBeUndefined();
1452
+ expect(config.yAxis.endOnTick).toBeUndefined();
1453
+ });
1454
+ });
1455
+
1456
+ describe('GIVEN: chartType does NOT support axis min/max', () => {
1457
+ test('THEN: xAxis min and max are ignored', () => {
1458
+ const params = {
1459
+ ...BASE_PARAMS,
1460
+ chartType: 'line',
1461
+ xAxis: {
1462
+ ...BASE_PARAMS.xAxis,
1463
+ min: 1,
1464
+ max: 10,
1465
+ startOnTick: true,
1466
+ endOnTick: true,
1467
+ },
1468
+ };
1469
+
1470
+ const $ = cheerio.load(renderComponent('chart', params));
1471
+ const configScript = $(`script[data-highcharts-config--${params.id}]`).html();
1472
+
1473
+ expect(configScript).not.toContain('"min":1');
1474
+ expect(configScript).not.toContain('"max":10');
1475
+ expect(configScript).not.toContain('"startOnTick":true');
1476
+ expect(configScript).not.toContain('"endOnTick":true');
1477
+ });
1478
+ });
1479
+ });
1480
+
1481
+ describe('FOR: Iframe chart', () => {
1482
+ describe('GIVEN: Params: Iframe chart', () => {
1483
+ describe('WHEN: an iframe url param is provided', () => {
1484
+ const $ = cheerio.load(renderComponent('chart', EXAMPLE_IFRAME_CHART_PARAMS));
1485
+
1486
+ test('THEN: it passes jest-axe checks', async () => {
1487
+ const results = await axe($.html());
1488
+ expect(results).toHaveNoViolations();
1489
+ });
1490
+
1491
+ test('THEN: it renders the iframe', () => {
1492
+ expect($('[data-chart-iframe]').length).toBe(1);
1493
+ });
1494
+
1495
+ test('THEN: it includes the iframe title as a data attribute', () => {
1496
+ const iframe = $('[data-chart-iframe]');
1497
+ expect(iframe.attr('data-title')).toBe(EXAMPLE_IFRAME_CHART_PARAMS.title);
1498
+ });
1499
+
1500
+ test('THEN: the theme parameter is ignored', () => {
1501
+ const $ = cheerio.load(
1502
+ renderComponent('chart', {
1503
+ ...EXAMPLE_IFRAME_CHART_PARAMS,
1504
+ theme: 'secondary',
1505
+ }),
1506
+ );
1507
+
1508
+ expect($('[data-highcharts-theme]').length).toBe(0);
1509
+ });
1510
+
1511
+ test('THEN: the percentageHeightDesktop and percentageHeightMobile parameters are ignored', () => {
1512
+ const $ = cheerio.load(
1513
+ renderComponent('chart', {
1514
+ ...EXAMPLE_IFRAME_CHART_PARAMS,
1515
+ percentageHeightDesktop: 50,
1516
+ percentageHeightMobile: 10,
1517
+ }),
1518
+ );
1519
+
1520
+ expect($('[data-highcharts-percentage-height-desktop]').length).toBe(0);
1521
+ expect($('[data-highcharts-percentage-height-mobile]').length).toBe(0);
1522
+ });
1523
+
1524
+ test('THEN: the tickIntervalDesktop and tickIntervalMobile parameters are ignored', () => {
1525
+ const $ = cheerio.load(
1526
+ renderComponent('chart', {
1527
+ ...EXAMPLE_IFRAME_CHART_PARAMS,
1528
+ xAxis: {
1529
+ tickIntervalDesktop: 10,
1530
+ tickIntervalMobile: 5,
1531
+ },
1532
+ yAxis: {
1533
+ tickIntervalDesktop: 10,
1534
+ tickIntervalMobile: 5,
1535
+ },
1536
+ }),
1537
+ );
1538
+
1539
+ expect($('[data-highcharts-x-axis-tick-interval-desktop]').length).toBe(0);
1540
+ expect($('[data-highcharts-x-axis-tick-interval-mobile]').length).toBe(0);
1541
+ expect($('[data-highcharts-y-axis-tick-interval-desktop]').length).toBe(0);
1542
+ expect($('[data-highcharts-y-axis-tick-interval-mobile]').length).toBe(0);
1543
+ });
1544
+
1545
+ test('THEN: the tickIntervalDesktop and tickIntervalMobile parameters are ignored', () => {
1546
+ const $ = cheerio.load(
1547
+ renderComponent('chart', {
1548
+ ...EXAMPLE_IFRAME_CHART_PARAMS,
1549
+ estimateLineLabel: 'Estimated value',
1550
+ uncertaintyRangeLabel: '95% Confidence Interval',
1551
+ }),
1552
+ );
1553
+
1554
+ expect($('[data-highcharts-estimate-line-label]').length).toBe(0);
1555
+ expect($('[data-highcharts-uncertainty-range-label]').length).toBe(0);
1556
+ });
1557
+
1558
+ test('THEN: the customReferenceLineValue parameter is ignored', () => {
1559
+ const $ = cheerio.load(
1560
+ renderComponent('chart', {
1561
+ ...EXAMPLE_IFRAME_CHART_PARAMS,
1562
+ yAxis: {
1563
+ customReferenceLineValue: 10,
1564
+ },
1565
+ }),
1566
+ );
1567
+
1568
+ expect($('[data-highcharts-custom-reference-line-value]').length).toBe(0);
1569
+ });
1570
+
1571
+ test('THEN: the legend for boxplot charts is not rendered', () => {
1572
+ const $ = cheerio.load(
1573
+ renderComponent('chart', {
1574
+ ...EXAMPLE_IFRAME_CHART_PARAMS,
1575
+ chartType: 'boxplot',
1576
+ legend: true,
1577
+ estimateLineLabel: 'Estimated value',
1578
+ uncertaintyRangeLabel: '95% Confidence Interval',
1579
+ }),
1580
+ );
1581
+
1582
+ expect($('.ons-chart__boxplot-legend').length).toBe(0);
1583
+ });
1584
+
1585
+ test('THEN: the Highcharts config is not included', () => {
1586
+ const configScript = $(`script[data-highcharts-config--iframe-chart-123]`).html();
1587
+ expect(configScript).toBeNull();
1588
+ });
1589
+
1590
+ test('THEN: the annotations footnotes and scripts are not rendered', () => {
1591
+ const $ = cheerio.load(
1592
+ renderComponent('chart', {
1593
+ ...EXAMPLE_IFRAME_CHART_PARAMS,
1594
+ annotations: [
1595
+ {
1596
+ text: 'A test point annotation',
1597
+ point: { x: 2, y: 3 },
1598
+ labelOffsetX: 10,
1599
+ labelOffsetY: -50,
1600
+ },
1601
+ ],
1602
+ rangeAnnotations: [
1603
+ {
1604
+ text: 'A test x axis range annotation',
1605
+ range: { axisValue1: 10, axisValue2: 15 },
1606
+ axis: 'x',
1607
+ labelOffsetX: 150,
1608
+ labelOffsetY: 0,
1609
+ },
1610
+ {
1611
+ text: 'A test y axis range annotation with the label inside',
1612
+ range: { axisValue1: 5, axisValue2: 10 },
1613
+ axis: 'y',
1614
+ labelInside: true,
1615
+ labelWidth: 250,
1616
+ },
1617
+ ],
1618
+ referenceLineAnnotations: [
1619
+ {
1620
+ text: 'A test x axis reference line annotation',
1621
+ value: 34,
1622
+ axis: 'x',
1623
+ },
1624
+ {
1625
+ text: 'A test y axis reference line annotation',
1626
+ value: 12,
1627
+ axis: 'y',
1628
+ labelWidth: 100,
1629
+ },
1630
+ ],
1631
+ }),
1632
+ );
1633
+
1634
+ expect($('[data-annotations-footnotes]').length).toBe(0);
1635
+ expect($('[data-highcharts-annotations--iframe-chart-123]').length).toBe(0);
1636
+ expect($('[data-highcharts-range-annotations--iframe-chart-123]').length).toBe(0);
1637
+ expect($('[data-highcharts-reference-line-annotations--iframe-chart-123]').length).toBe(0);
1638
+ });
1639
+
1640
+ test('THEN: invalid chart type is ignored', () => {
1641
+ const $ = cheerio.load(
1642
+ renderComponent('chart', {
1643
+ ...EXAMPLE_IFRAME_CHART_PARAMS,
1644
+ chartType: 'foobar',
1645
+ }),
1646
+ );
1647
+
1648
+ expect($('[data-invalid-chart-type]').length).toBe(0);
1293
1649
  });
1294
1650
  });
1295
1651
  });
@@ -49,7 +49,7 @@ class AnnotationsOptions {
49
49
  borderColor: 'transparent',
50
50
  // We use css styling for the rounded number annotation at mobile
51
51
  useHTML: true,
52
- className: 'ons-chart__footnote-number',
52
+ className: 'ons-chart__annotations-footnotes-number',
53
53
  },
54
54
  draggable: '',
55
55
  },
@@ -38,6 +38,7 @@ class BarChart {
38
38
  // Update the category label colours for bar charts
39
39
  labels: {
40
40
  style: {
41
+ textOverflow: 'ellipsis',
41
42
  color: this.constants.categoryLabelColor,
42
43
  },
43
44
  useHTML: false,
@@ -0,0 +1,8 @@
1
+ import ChartIframeResize from './chart-iframe-resize';
2
+ import domready from '../../js/domready';
3
+
4
+ domready(async () => {
5
+ [ChartIframeResize].forEach((Component) => {
6
+ document.querySelectorAll(Component.selector()).forEach((el) => new Component(el));
7
+ });
8
+ });
@@ -0,0 +1,16 @@
1
+ import pym from 'pym.js';
2
+
3
+ class ChartIframeResize {
4
+ static selector() {
5
+ return '[data-chart-iframe]';
6
+ }
7
+
8
+ constructor(node) {
9
+ this.node = node;
10
+ new pym.Parent(this.node.getAttribute('id'), this.node.dataset.url, {
11
+ title: this.node.dataset.title,
12
+ });
13
+ }
14
+ }
15
+
16
+ export default ChartIframeResize;
@@ -31,6 +31,11 @@ class HighchartsBaseChart {
31
31
  console.error('No chart node found');
32
32
  return;
33
33
  }
34
+
35
+ // Add a CSS class to the chart based on the chart type (e.g., 'bar-chart-container', 'line-chart-container')
36
+ // This allows type-specific styling in CSS.
37
+ chartNode.classList.add(`${this.chartType}-chart-container`);
38
+
34
39
  this.id = this.node.dataset.highchartsId;
35
40
  this.useStackedLayout = this.node.hasAttribute('data-highcharts-use-stacked-layout');
36
41
  this.config = JSON.parse(this.node.querySelector(`[data-highcharts-config--${this.id}]`).textContent);
@@ -0,0 +1,72 @@
1
+ {% from "components/chart/_macro.njk" import onsChart %}
2
+
3
+ {{
4
+ onsChart({
5
+ "chartType": "area",
6
+ "description": "Area chart showing the annual rate of inflation for the Consumer Prices Index including owner occupiers’ housing costs (CPIH) and its components.",
7
+ "theme": "alternate",
8
+ "title": "Sales volumes and values saw moderate growth in July 2024",
9
+ "subtitle": "Figure 6: Upward contribution from housing and household services (including energy) saw the annual CPIH inflation rate rise",
10
+ "id": "id",
11
+ "headingLevel": 4,
12
+ "caption": "Source: Monthly Business Survey, Retails Sales Inquiry from the Office for National Statistics",
13
+ "download": {
14
+ 'title': 'Download Figure 1 data',
15
+ 'itemsList': [
16
+ {
17
+ "text": "Excel spreadsheet (XLSX format, 18KB)",
18
+ "url": "#"
19
+ },
20
+ {
21
+ "text": "Simple text file (CSV format, 25KB)",
22
+ "url": "#"
23
+ },
24
+ {
25
+
26
+ "text": "Image (PNG format, 25KB)",
27
+ "url": "#"
28
+ }
29
+ ]},
30
+ "legend": "true",
31
+ "series": [
32
+ {
33
+ "data": [
34
+ 39.2, 47.1, 44.0, 46, 65.3, 53.2, 49.1, 49.3, 50.4, 48.1,
35
+ 43.9, 41.8
36
+ ],
37
+ "name": "Test series 3"
38
+ },
39
+ {
40
+ "data": [
41
+ 28.8, 23.2, 33.0, 25.8, 20.8, 39.8, 37.9, 28.2, 37.6, 46.7,
42
+ 43.9, 41.8
43
+ ],
44
+ "name": "Test series 2"
45
+ },
46
+ {
47
+ "data": [
48
+ 37.8, 41.0, 43.0, 42.9, 41.8, 39.8, 37.9, 38.2, 37.6, 36.7,
49
+ 33.9, 31.8
50
+ ],
51
+ "name": "Test series 1"
52
+ }
53
+ ],
54
+ "xAxis": {
55
+ "categories": [
56
+ "Mar 1901", "Mar 1902", "Mar 1903", "Mar 1904", "Mar 1905", "Mar 1906", "Mar 1907", "Mar 1908", "Mar 1909", "Mar 1910",
57
+ "Mar 1911", "Mar 1912"
58
+ ],
59
+ "title": "Years",
60
+ "type": "linear"
61
+ },
62
+ "yAxis": {
63
+ "title": "Y axis title",
64
+ "min": -25,
65
+ "max": 150,
66
+ "startOnTick": true,
67
+ "endOnTick": false
68
+ },
69
+ "percentageHeightDesktop": 50,
70
+ "percentageHeightMobile": 120
71
+ })
72
+ }}
@@ -0,0 +1,59 @@
1
+ {% from "components/chart/_macro.njk" import onsChart %}
2
+
3
+ {{
4
+ onsChart({
5
+ "chartType": "bar",
6
+ "description": "Volume sales, seasonally adjusted, Great Britain, January 2022 to January 2025",
7
+ "theme": "primary",
8
+ "title": "Food stores showed a strong rise on the month, while non-food stores fell",
9
+ "subtitle": "Figure 6: Upward contribution from housing and household services (including energy) saw the annual CPIH inflation rate rise",
10
+ "id": "uuid",
11
+ "caption": "Source: Monthly Business Survey, Retail Sales Inquiry from the Office for National Statistics",
12
+ "download": {
13
+ 'title': 'Download Figure 1 data',
14
+ 'itemsList': [
15
+ {
16
+ "text": "Excel spreadsheet (XLSX format, 18KB)",
17
+ "url": "#"
18
+ },
19
+ {
20
+ "text": "Simple text file (CSV format, 25KB)",
21
+ "url": "#"
22
+ },
23
+ {
24
+ "text": "Image (PNG format, 25KB)",
25
+ "url": "#"
26
+ }
27
+ ]
28
+ },
29
+ "xAxis": {
30
+ "categories": [
31
+ "All retailing",
32
+ "All retailing excluding Automotive fuel",
33
+ "Food stores",
34
+ "Department stores",
35
+ "Other non-food stores",
36
+ "Textile clothing \u0026 footwear stores",
37
+ "Household goods stores",
38
+ "Non-store retailing",
39
+ "Automotive fuel"
40
+ ],
41
+ "title": "Retailing",
42
+ "type": "linear"
43
+ },
44
+ "yAxis": {
45
+ "title": "Percent (%)",
46
+ "min": -5,
47
+ "max": 10,
48
+ "startOnTick": true,
49
+ "endOnTick": false
50
+ },
51
+ "series": [
52
+ {
53
+ "data": [1.7, 2.1, 5.6, 0, -0.6, -2.7, -1.7, 2.4, -1.2],
54
+ "dataLabels": true,
55
+ "name": "Jan-25"
56
+ }
57
+ ]
58
+ })
59
+ }}
@@ -26,6 +26,10 @@
26
26
  }
27
27
  ]
28
28
  },
29
+ "footnotes": {
30
+ "title": "Footnotes",
31
+ "content": "<ol><li>Non-store retailing refers to retailers that do not have a store presence. While the majority is made up of online retailers, it also includes other retailers, such as stalls and markets.</li><li>More data are available in our Retail Sales Index datasets.</li></ol>"
32
+ },
29
33
  "xAxis": {
30
34
  "categories": [
31
35
  "All retailing",