@ons/design-system 74.0.0-next.6 → 74.0.0-next.8

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 (65) hide show
  1. package/components/breadcrumbs/example-breadcrumbs-wide.njk +52 -0
  2. package/components/chart/_chart.scss +0 -9
  3. package/components/chart/_macro.njk +96 -128
  4. package/components/chart/_macro.spec.js +43 -28
  5. package/components/chart/example-area-chart-with-axis-min-and-max-values.njk +6 -3
  6. package/components/chart/example-area-chart.njk +6 -3
  7. package/components/chart/example-bar-chart-with-annotations.njk +6 -3
  8. package/components/chart/example-bar-chart-with-axis-min-and-max-values.njk +6 -3
  9. package/components/chart/example-bar-chart-with-point-range-and-reference-line-annotations.njk +6 -3
  10. package/components/chart/example-bar-chart.njk +6 -3
  11. package/components/chart/example-bar-with-confidence-levels.njk +6 -3
  12. package/components/chart/example-clustered-bar-chart.njk +6 -3
  13. package/components/chart/example-clustered-column-chart.njk +6 -3
  14. package/components/chart/example-column-chart-with-annotations.njk +6 -3
  15. package/components/chart/example-column-chart-with-axis-min-and-max-values.njk +6 -3
  16. package/components/chart/example-column-chart-with-custom-reference-line-value.njk +6 -3
  17. package/components/chart/example-column-chart-with-range-annotations.njk +6 -3
  18. package/components/chart/example-column-chart-with-reference-line-annotations.njk +6 -3
  19. package/components/chart/example-column-chart.njk +6 -3
  20. package/components/chart/example-column-with-confidence-levels.njk +6 -3
  21. package/components/chart/example-column-with-line-chart.njk +6 -3
  22. package/components/chart/example-iframe-chart.njk +6 -3
  23. package/components/chart/example-line-chart-with-annotations.njk +6 -3
  24. package/components/chart/example-line-chart-with-axis-min-and-max-values.njk +6 -3
  25. package/components/chart/example-line-chart-with-custom-reference-line-value.njk +6 -3
  26. package/components/chart/example-line-chart-with-label-format.njk +6 -3
  27. package/components/chart/example-line-chart-with-markers.njk +6 -3
  28. package/components/chart/example-line-chart-with-range-annotations-inside.njk +6 -3
  29. package/components/chart/example-line-chart-with-range-annotations-outside-left-right.njk +6 -3
  30. package/components/chart/example-line-chart-with-range-annotations-outside-top-bottom.njk +6 -3
  31. package/components/chart/example-line-chart-with-reference-line-annotations.njk +6 -3
  32. package/components/chart/example-line-chart.njk +6 -3
  33. package/components/chart/example-scatter-chart-with-axis-min-and-max-values.njk +6 -3
  34. package/components/chart/example-scatter-chart.njk +6 -3
  35. package/components/chart/example-stacked-bar-chart.njk +6 -3
  36. package/components/chart/example-stacked-column-chart.njk +6 -3
  37. package/components/document-list/_macro.njk +2 -2
  38. package/components/document-list/_macro.spec.js +55 -0
  39. package/components/featured-article/_macro.njk +3 -37
  40. package/components/featured-article/example-featured-article-with-chart.njk +19 -14
  41. package/components/featured-article/example-featured-article-with-image.njk +12 -7
  42. package/components/featured-article/featured-article.scss +1 -1
  43. package/components/featured-article/macro.spec.js +44 -67
  44. package/components/figure/_figure.scss +31 -0
  45. package/components/figure/_macro.njk +98 -0
  46. package/components/figure/_macro.spec.js +520 -0
  47. package/components/figure/example-figure-heading-level-2.njk +34 -0
  48. package/components/figure/example-figure-with-div.njk +29 -0
  49. package/components/figure/example-figure-without-footer.njk +12 -0
  50. package/components/figure/example-figure-without-header.njk +24 -0
  51. package/components/figure/example-figure.njk +34 -0
  52. package/components/image/_image.scss +0 -7
  53. package/components/image/_macro.njk +25 -14
  54. package/components/image/_macro.spec.js +122 -7
  55. package/components/image/example-image-with-figure-fields.njk +25 -0
  56. package/components/list/_macro.njk +1 -0
  57. package/components/list/_macro.spec.js +16 -0
  58. package/components/table/_macro.njk +138 -111
  59. package/components/table/_macro.spec.js +172 -2
  60. package/components/table/_table.scss +6 -1
  61. package/components/table/example-table-with-figure-fields.njk +86 -0
  62. package/css/main.css +1 -1
  63. package/layout/_template.njk +1 -0
  64. package/package.json +2 -2
  65. package/scss/main.scss +1 -0
@@ -277,6 +277,61 @@ describe('FOR: Macro: Document list', () => {
277
277
  expect(fileInfo).toBe('PDF, 499KB, 1 page');
278
278
  });
279
279
  });
280
+
281
+ describe('WHEN: file configuration is missing optional fileSize and filePages', () => {
282
+ const $ = cheerio.load(
283
+ renderComponent('document-list', {
284
+ documents: [
285
+ {
286
+ ...EXAMPLE_DOCUMENT_LIST_BASIC,
287
+ metadata: {
288
+ file: {
289
+ fileType: 'PDF',
290
+ },
291
+ },
292
+ },
293
+ ],
294
+ }),
295
+ );
296
+
297
+ test('THEN: has visually hidden file information without stray separators', () => {
298
+ const hiddenText = $('.ons-document-list__item-title a .ons-u-vh').text().trim();
299
+ expect(hiddenText).toBe(', PDF document download');
300
+ });
301
+
302
+ test('THEN: has file information without stray separators', () => {
303
+ const fileInfo = $('.ons-document-list__item-attribute').text().trim();
304
+ expect(fileInfo).toBe('PDF');
305
+ });
306
+ });
307
+
308
+ describe('WHEN: file configuration is missing optional filePages', () => {
309
+ const $ = cheerio.load(
310
+ renderComponent('document-list', {
311
+ documents: [
312
+ {
313
+ ...EXAMPLE_DOCUMENT_LIST_BASIC,
314
+ metadata: {
315
+ file: {
316
+ fileType: 'PDF',
317
+ fileSize: '499KB',
318
+ },
319
+ },
320
+ },
321
+ ],
322
+ }),
323
+ );
324
+
325
+ test('THEN: has visually hidden file information without stray separators', () => {
326
+ const hiddenText = $('.ons-document-list__item-title a .ons-u-vh').text().trim();
327
+ expect(hiddenText).toBe(', PDF document download, 499KB');
328
+ });
329
+
330
+ test('THEN: has file information without stray separators', () => {
331
+ const fileInfo = $('.ons-document-list__item-attribute').text().trim();
332
+ expect(fileInfo).toBe('PDF, 499KB');
333
+ });
334
+ });
280
335
  });
281
336
 
282
337
  describe('GIVEN: Params: object', () => {
@@ -1,6 +1,3 @@
1
- {% from "components/chart/_macro.njk" import onsChart %}
2
- {% from "components/image/_macro.njk" import onsImage %}
3
-
4
1
  {% macro onsFeaturedArticle(params) %}
5
2
  {% set headingLevel = params.headingLevel | default(2) %}
6
3
  {% set openingArticleTitleTag = "<h" ~ headingLevel %}
@@ -32,41 +29,10 @@
32
29
  </ul>
33
30
  {% endif %}
34
31
 
32
+ {# The media (a nested figure containing a chart or image) is provided via the caller
33
+ block, so the article does not need to know how the content is rendered. #}
35
34
  <div class="ons-featured__media">
36
- {% if params.chart %}
37
- {{
38
- onsChart({
39
- "chartType": params.chart.chartType,
40
- "description": params.chart.description,
41
- "theme": params.chart.theme,
42
- "title": params.chart.title,
43
- "id": params.chart.id,
44
- "headingLevel": headingLevel + 1,
45
- "legend": params.chart.legend,
46
- "xAxis": params.chart.xAxis,
47
- "yAxis": params.chart.yAxis,
48
- "series": params.chart.series,
49
- "annotations": params.chart.annotations,
50
- "rangeAnnotations": params.chart.rangeAnnotations,
51
- "referenceLineAnnotations": params.chart.referenceLineAnnotations,
52
- "estimateLineLabel": params.chart.estimateLineLabel,
53
- "uncertaintyRangeLabel": params.chart.uncertaintyRangeLabel,
54
- "isChartInverted": params.chart.isChartInverted,
55
- "useStackedLayout": params.chart.useStackedLayout,
56
- "percentageHeightDesktop": params.chart.percentageHeightDesktop,
57
- "percentageHeightMobile": params.chart.percentageHeightMobile
58
- })
59
- }}
60
- {% elif params.image %}
61
- <div class="ons-featured__image">
62
- {{
63
- onsImage({
64
- "src": params.image.src,
65
- "alt": params.image.alt
66
- })
67
- }}
68
- </div>
69
- {% endif %}
35
+ {{ caller() if caller }}
70
36
  </div>
71
37
 
72
38
  {% if params.description %}
@@ -1,6 +1,8 @@
1
1
  {% from "components/featured-article/_macro.njk" import onsFeaturedArticle %}
2
- {{
3
- onsFeaturedArticle({
2
+ {% from "components/chart/_macro.njk" import onsChart %}
3
+
4
+ {%
5
+ call onsFeaturedArticle({
4
6
  "title": {
5
7
  "text": 'Retail sales, Great Britain: July 2024',
6
8
  "url": '#0'
@@ -15,14 +17,22 @@
15
17
  }
16
18
  },
17
19
  "headingLevel": 3,
18
- "chart": {
20
+ "description": "<ul>
21
+ <li>Retail sales volumes increased by 0.4% in July 2024, following a 0.2% increase in June 2024.</li>
22
+ <li>Retail sales values increased by 0.5% in July 2024, following a 0.3% increase in June 2024.</li>
23
+ <li>The annual rate of inflation for the Consumer Prices Index including owner occupiers’ housing costs (CPIH) was 2.8% in July 2024, up from 2.6% in June 2024.</li>
24
+ </ul>"
25
+ })
26
+ %}
27
+
28
+ {{
29
+ onsChart({
19
30
  "chartType": "line",
20
- "description": "Line chart showing the annual rate of inflation for the Consumer Prices Index including owner occupiers’ housing costs (CPIH) and its components.",
21
31
  "theme": "primary",
32
+ "headingLevel": 4,
22
33
  "title": "Sales volumes and values saw moderate growth in July 2024",
23
- "subtitle": "Figure 6: Upward contribution from housing and household services (including energy) saw the annual CPIH inflation rate rise",
34
+ "audioDescription": "Line chart showing the annual rate of inflation for the Consumer Prices Index including owner occupiers’ housing costs (CPIH) and its components.",
24
35
  "id": "id",
25
- "headingLevel": 4,
26
36
  "legend": true,
27
37
  "xAxis": {
28
38
  "title": "Year",
@@ -213,11 +223,6 @@
213
223
  ],
214
224
  "percentageHeightDesktop": 35,
215
225
  "percentageHeightMobile": 90
216
- },
217
- "description": "<ul>
218
- <li>Retail sales volumes increased by 0.4% in July 2024, following a 0.2% increase in June 2024.</li>
219
- <li>Retail sales values increased by 0.5% in July 2024, following a 0.3% increase in June 2024.</li>
220
- <li>The annual rate of inflation for the Consumer Prices Index including owner occupiers’ housing costs (CPIH) was 2.8% in July 2024, up from 2.6% in June 2024.</li>
221
- </ul>"
222
- })
223
- }}
226
+ })
227
+ }}
228
+ {% endcall %}
@@ -1,6 +1,8 @@
1
1
  {% from "components/featured-article/_macro.njk" import onsFeaturedArticle %}
2
- {{
3
- onsFeaturedArticle({
2
+ {% from "components/image/_macro.njk" import onsImage %}
3
+
4
+ {%
5
+ call onsFeaturedArticle({
4
6
  "title": {
5
7
  "text": 'Retail sales, Great Britain: July 2024',
6
8
  "url": '#0'
@@ -15,10 +17,13 @@
15
17
  }
16
18
  },
17
19
  "headingLevel": 3,
18
- "image": {
19
- "src": '/img/small/census-monuments-lights-featured.jpg',
20
- "alt": 'census monuments lights featured'
21
- },
22
20
  "description": "Retail sales volumes and values saw moderate growth in July 2024, with the annual rate of inflation for the Consumer Prices Index including owner occupiers’ housing costs (CPIH) rising to 2.8%."
23
21
  })
24
- }}
22
+ %}
23
+ {{
24
+ onsImage({
25
+ "src": '/img/small/census-monuments-lights-featured.jpg',
26
+ "alt": 'census monuments lights featured'
27
+ })
28
+ }}
29
+ {% endcall %}
@@ -6,7 +6,7 @@
6
6
  outline: 2px solid transparent;
7
7
  outline-offset: -2px;
8
8
 
9
- &__image {
9
+ &__media {
10
10
  .ons-image__img {
11
11
  width: 100%;
12
12
  max-width: $grid-max-width;
@@ -3,12 +3,12 @@
3
3
  import * as cheerio from 'cheerio';
4
4
  import axe from '../../tests/helpers/axe';
5
5
  import { renderComponent } from '../../tests/helpers/rendering';
6
- import { EXAMPLE_FEATURED_ARTICLE_WITH_CHART, EXAMPLE_FEATURED_ARTICLE_WITH_IMAGE } from './_test-examples';
6
+ import { EXAMPLE_FEATURED_ARTICLE_PARAMS, EXAMPLE_CHART_CALLER_CONTENT, EXAMPLE_IMAGE_CALLER_CONTENT } from './_test-examples';
7
7
 
8
8
  describe('Macro: Featured Article', () => {
9
9
  describe('GIVEN: Params: required', () => {
10
- describe('WHEN: chart is provided and image is not', () => {
11
- const $ = cheerio.load(renderComponent('featured-article', EXAMPLE_FEATURED_ARTICLE_WITH_CHART));
10
+ describe('WHEN: chart content is provided via caller', () => {
11
+ const $ = cheerio.load(renderComponent('featured-article', EXAMPLE_FEATURED_ARTICLE_PARAMS, EXAMPLE_CHART_CALLER_CONTENT));
12
12
 
13
13
  test('THEN: it passes accessibility checks', async () => {
14
14
  const results = await axe($.html());
@@ -23,8 +23,8 @@ describe('Macro: Featured Article', () => {
23
23
  expect($('.ons-featured__title a').attr('href')).toBe('/economy/economic-trends-2024');
24
24
  });
25
25
 
26
- test('THEN: it renders the onsChart component', () => {
27
- expect($('[data-highcharts-base-chart]').length).toBe(1);
26
+ test('THEN: it renders the caller content in the media area', () => {
27
+ expect($('.ons-featured__media [data-highcharts-base-chart]').length).toBe(1);
28
28
  });
29
29
 
30
30
  test('THEN: the chart has the correct id', () => {
@@ -36,8 +36,8 @@ describe('Macro: Featured Article', () => {
36
36
  });
37
37
  });
38
38
 
39
- describe('WHEN: image is provided and chart is not', () => {
40
- const $ = cheerio.load(renderComponent('featured-article', EXAMPLE_FEATURED_ARTICLE_WITH_IMAGE));
39
+ describe('WHEN: image content is provided via caller', () => {
40
+ const $ = cheerio.load(renderComponent('featured-article', EXAMPLE_FEATURED_ARTICLE_PARAMS, EXAMPLE_IMAGE_CALLER_CONTENT));
41
41
 
42
42
  test('THEN: it passes accessibility checks', async () => {
43
43
  const results = await axe($.html());
@@ -45,78 +45,50 @@ describe('Macro: Featured Article', () => {
45
45
  });
46
46
 
47
47
  test('THEN: it displays the correct title text', () => {
48
- expect($('.ons-featured__title').text().trim()).toBe('Population Insights');
48
+ expect($('.ons-featured__title').text().trim()).toBe('Economic Trends 2024');
49
49
  });
50
50
 
51
51
  test('THEN: the title has the correct url link', () => {
52
- expect($('.ons-featured__title a').attr('href')).toBe('/people/population/insights');
52
+ expect($('.ons-featured__title a').attr('href')).toBe('/economy/economic-trends-2024');
53
53
  });
54
54
 
55
55
  test('THEN: it renders image with correct src attribute', () => {
56
- expect($('.ons-image__img').attr('src')).toBe('example.png');
56
+ expect($('.ons-featured__media .ons-image__img').attr('src')).toBe('example.png');
57
57
  });
58
58
 
59
59
  test('THEN: it renders image with correct alt text', () => {
60
- expect($('.ons-image__img').attr('alt')).toBe('Example alt text');
60
+ expect($('.ons-featured__media .ons-image__img').attr('alt')).toBe('Example alt text');
61
61
  });
62
62
  });
63
63
 
64
- describe('WHEN: both chart and image is provided', () => {
65
- const $ = cheerio.load(renderComponent('featured-article', EXAMPLE_FEATURED_ARTICLE_WITH_CHART));
64
+ describe('WHEN: no caller content is provided', () => {
65
+ const $ = cheerio.load(renderComponent('featured-article', EXAMPLE_FEATURED_ARTICLE_PARAMS));
66
66
 
67
- test('THEN: it renders the onsChart component', () => {
68
- expect($('[data-highcharts-base-chart]').length).toBe(1);
69
- });
70
- test('THEN: it does not render the onsImage component', () => {
71
- expect($('.ons-image__img').length).toBe(0);
67
+ test('THEN: the media area is empty', () => {
68
+ expect($('.ons-featured__media').html().trim()).toBe('');
72
69
  });
73
70
  });
74
71
  });
75
72
 
76
73
  describe('GIVEN: Param: metadata', () => {
77
- describe('WHEN: chart is provided', () => {
78
- const $ = cheerio.load(
79
- renderComponent('featured-article', {
80
- ...EXAMPLE_FEATURED_ARTICLE_WITH_CHART,
81
- metadata: {
82
- date: {
83
- prefix: 'Released',
84
- showPrefix: true,
85
- iso: '2024-05-01',
86
- short: '1 May 2024',
87
- },
88
- text: 'Bulletin',
89
- },
90
- }),
91
- );
92
-
93
- test('THEN: it renders ISO date value correctly', () => {
94
- expect($('time').attr('datetime')).toBe('2024-05-01');
95
- });
96
-
97
- test('THEN: it renders short date label correctly', () => {
98
- expect($('time').text()).toBe('1 May 2024');
99
- });
100
-
101
- test('THEN: it displays metadata text', () => {
102
- expect($('.ons-featured__item-attribute span').text()).toContain('Bulletin');
103
- });
104
- });
105
-
106
- describe('WHEN: image is provided', () => {
74
+ describe('WHEN: metadata is provided', () => {
107
75
  const $ = cheerio.load(
108
- renderComponent('featured-article', {
109
- ...EXAMPLE_FEATURED_ARTICLE_WITH_IMAGE,
110
- metadata: {
111
- date: {
112
- prefix: 'Released',
113
- showPrefix: true,
114
- iso: '2024-05-01',
115
- short: '1 May 2024',
76
+ renderComponent(
77
+ 'featured-article',
78
+ {
79
+ ...EXAMPLE_FEATURED_ARTICLE_PARAMS,
80
+ metadata: {
81
+ date: {
82
+ prefix: 'Released',
83
+ showPrefix: true,
84
+ iso: '2024-05-01',
85
+ short: '1 May 2024',
86
+ },
87
+ text: 'Bulletin',
116
88
  },
117
- text: 'Bulletin',
118
89
  },
119
- }),
90
+ EXAMPLE_CHART_CALLER_CONTENT,
91
+ ),
120
92
  );
121
93
 
122
94
  test('THEN: it renders ISO date value correctly', () => {
@@ -133,10 +105,7 @@ describe('Macro: Featured Article', () => {
133
105
  });
134
106
 
135
107
  describe('WHEN: metadata is not provided', () => {
136
- const articleWithoutMetadata = {
137
- ...EXAMPLE_FEATURED_ARTICLE_WITH_CHART,
138
- };
139
- const $ = cheerio.load(renderComponent('featured-article', articleWithoutMetadata));
108
+ const $ = cheerio.load(renderComponent('featured-article', EXAMPLE_FEATURED_ARTICLE_PARAMS, EXAMPLE_CHART_CALLER_CONTENT));
140
109
 
141
110
  test('THEN: metadata section is not rendered', () => {
142
111
  expect($('.ons-featured__item-metadata').length).toBe(0);
@@ -148,7 +117,11 @@ describe('Macro: Featured Article', () => {
148
117
  describe('WHEN: description is provided', () => {
149
118
  test('THEN: has expected description', () => {
150
119
  const $ = cheerio.load(
151
- renderComponent('featured-article', { ...EXAMPLE_FEATURED_ARTICLE_WITH_CHART, description: 'Some description' }),
120
+ renderComponent(
121
+ 'featured-article',
122
+ { ...EXAMPLE_FEATURED_ARTICLE_PARAMS, description: 'Some description' },
123
+ EXAMPLE_CHART_CALLER_CONTENT,
124
+ ),
152
125
  );
153
126
  const title = $('.ons-featured__description').html().trim();
154
127
  expect(title).toBe('Some description');
@@ -159,10 +132,14 @@ describe('Macro: Featured Article', () => {
159
132
  describe('GIVEN: Param: headingLevel', () => {
160
133
  describe('WHEN: heading level is provided', () => {
161
134
  const $ = cheerio.load(
162
- renderComponent('featured-article', {
163
- ...EXAMPLE_FEATURED_ARTICLE_WITH_CHART,
164
- headingLevel: 3,
165
- }),
135
+ renderComponent(
136
+ 'featured-article',
137
+ {
138
+ ...EXAMPLE_FEATURED_ARTICLE_PARAMS,
139
+ headingLevel: 3,
140
+ },
141
+ EXAMPLE_CHART_CALLER_CONTENT,
142
+ ),
166
143
  );
167
144
 
168
145
  test('THEN: title is rendered using correct heading tag', () => {
@@ -0,0 +1,31 @@
1
+ .ons-figure {
2
+ margin: 0;
3
+
4
+ &__number {
5
+ color: var(--ons-color-text-light);
6
+ font-size: 1.125rem;
7
+ font-weight: $font-weight-bold;
8
+ line-height: 1.3;
9
+ }
10
+
11
+ &__title {
12
+ font-size: 1.25rem;
13
+ line-height: 1.6;
14
+ font-weight: $font-weight-bold;
15
+ margin-bottom: 0.5rem;
16
+ }
17
+
18
+ &__subtitle {
19
+ font-size: 1.125rem;
20
+ line-height: 1.6;
21
+ font-weight: $font-weight-regular;
22
+ }
23
+
24
+ &__caption {
25
+ color: var(--ons-color-text-light);
26
+ font-size: 0.875rem;
27
+ line-height: 1.7;
28
+ display: block;
29
+ margin-bottom: 1.5rem;
30
+ }
31
+ }
@@ -0,0 +1,98 @@
1
+ {% from "components/list/_macro.njk" import onsList %}
2
+ {% from "components/details/_macro.njk" import onsDetails %}
3
+
4
+ {% macro onsFigure(params) %}
5
+ {# The heading levels are configurable so the figure slots into the correct place in the
6
+ document outline, but the title and subtitle always render at the same visual size
7
+ via the utility font-size classes below. #}
8
+ {% set headingLevel = params.headingLevel | default(2, true) %}
9
+ {% set openingTitleTag = '<h' ~ headingLevel ~ ' class="ons-figure__title">' %}
10
+ {% set closingTitleTag = "</h" ~ headingLevel ~ ">" %}
11
+ {% set openingSubtitleTag = '<h' ~ (headingLevel + 1) ~ ' class="ons-figure__subtitle">' %}
12
+ {% set closingSubtitleTag = "</h" ~ (headingLevel + 1) ~ ">" %}
13
+ {% if params.title and params.subtitle %}
14
+ {% set childHeadingLevel = headingLevel + 2 %}
15
+ {% elif params.title %}
16
+ {% set childHeadingLevel = headingLevel + 1 %}
17
+ {% else %}
18
+ {% set childHeadingLevel = headingLevel %}
19
+ {% endif %}
20
+ {% set audioDescriptionId = "figure-audio-description-" ~ params.id %}
21
+ {% set rootElement = 'div' if params.useDivForRootElement else 'figure' %}
22
+ {% set openingRootTag = '<' ~ rootElement %}
23
+ {% if params.audioDescription %}
24
+ {% set openingRootTag = openingRootTag ~ ' aria-describedby="' ~ audioDescriptionId ~ '"' %}
25
+ {% endif %}
26
+ {% set openingRootTag = openingRootTag ~ ' class="ons-figure' ~ (' ' ~ params.classes if params.classes else '') ~ '"' %}
27
+ {% if params.id %}
28
+ {% set openingRootTag = openingRootTag ~ ' id="' ~ params.id ~ '"' %}
29
+ {% endif %}
30
+ {% set openingRootTag = openingRootTag ~ '>' %}
31
+ {% set closingRootTag = '</' ~ rootElement ~ '>' %}
32
+ {% set contentHasTopMargin = true if params.figureNumber or params.title or params.subtitle else false %}
33
+ {% set contentHasBottomMargin = true if params.caption or params.footnotes or params.download else false %}
34
+
35
+ {{ openingRootTag | safe }}
36
+ {% if params.figureNumber %}
37
+ <span class="ons-figure__number">{{ params.figureNumber }}</span>
38
+ {% endif %}
39
+ {% if params.title %}
40
+ {{ openingTitleTag | safe }}{{ params.title }}{{ closingTitleTag | safe }}
41
+ {% endif %}
42
+ {% if params.subtitle and params.title %}
43
+ {{ openingSubtitleTag | safe }}{{ params.subtitle }}{{ closingSubtitleTag | safe }}
44
+ {% endif %}
45
+
46
+ {# A visually-hidden description of the nested content for screen reader users. #}
47
+ {% if params.audioDescription %}
48
+ <p class="ons-u-vh" id="{{ audioDescriptionId }}">{{ params.audioDescription }}</p>
49
+ {% endif %}
50
+
51
+ <div
52
+ class="
53
+ ons-figure__content
54
+ {% if contentHasTopMargin %}ons-u-mt-l{% endif %}
55
+ {% if contentHasBottomMargin %}ons-u-mb-l{% endif %}
56
+ "
57
+ >
58
+ {# The nested content appears here #}
59
+ {{ caller() if caller else '' }}
60
+ </div>
61
+
62
+ {% if params.caption %}
63
+ {% if rootElement == 'figure' %}
64
+ <figcaption class="ons-figure__caption">{{ params.caption }}</figcaption>
65
+ {% else %}
66
+ <span class="ons-figure__caption">{{ params.caption }}</span>
67
+ {% endif %}
68
+ {% endif %}
69
+ {{ closingRootTag | safe }}
70
+
71
+ {% if params.footnotes %}
72
+ {% set footnotesId = ["figure-footnotes--", params.id] | join %}
73
+ {{
74
+ onsDetails({
75
+ "id": footnotesId,
76
+ "title": params.footnotes.title,
77
+ "content": params.footnotes.content,
78
+ "headingLevel": childHeadingLevel,
79
+ "classes": "ons-u-mb-l"
80
+ })
81
+ }}
82
+ {% endif %}
83
+
84
+ {% if params.download.title and params.download.itemsList | length > 0 %}
85
+ {% set downloadsId = ["figure-downloads--", params.id] | join %}
86
+ {{
87
+ onsDetails({
88
+ "id": downloadsId,
89
+ "title": params.download.title,
90
+ "content": onsList({
91
+ "itemsList": params.download.itemsList,
92
+ "variants": "bare"
93
+ }),
94
+ "headingLevel": childHeadingLevel
95
+ })
96
+ }}
97
+ {% endif %}
98
+ {% endmacro %}