@ons/design-system 74.0.0-next.6 → 74.0.0-next.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 (63) hide show
  1. package/components/chart/_chart.scss +0 -9
  2. package/components/chart/_macro.njk +96 -128
  3. package/components/chart/_macro.spec.js +43 -28
  4. package/components/chart/example-area-chart-with-axis-min-and-max-values.njk +6 -3
  5. package/components/chart/example-area-chart.njk +6 -3
  6. package/components/chart/example-bar-chart-with-annotations.njk +6 -3
  7. package/components/chart/example-bar-chart-with-axis-min-and-max-values.njk +6 -3
  8. package/components/chart/example-bar-chart-with-point-range-and-reference-line-annotations.njk +6 -3
  9. package/components/chart/example-bar-chart.njk +6 -3
  10. package/components/chart/example-bar-with-confidence-levels.njk +6 -3
  11. package/components/chart/example-clustered-bar-chart.njk +6 -3
  12. package/components/chart/example-clustered-column-chart.njk +6 -3
  13. package/components/chart/example-column-chart-with-annotations.njk +6 -3
  14. package/components/chart/example-column-chart-with-axis-min-and-max-values.njk +6 -3
  15. package/components/chart/example-column-chart-with-custom-reference-line-value.njk +6 -3
  16. package/components/chart/example-column-chart-with-range-annotations.njk +6 -3
  17. package/components/chart/example-column-chart-with-reference-line-annotations.njk +6 -3
  18. package/components/chart/example-column-chart.njk +6 -3
  19. package/components/chart/example-column-with-confidence-levels.njk +6 -3
  20. package/components/chart/example-column-with-line-chart.njk +6 -3
  21. package/components/chart/example-iframe-chart.njk +6 -3
  22. package/components/chart/example-line-chart-with-annotations.njk +6 -3
  23. package/components/chart/example-line-chart-with-axis-min-and-max-values.njk +6 -3
  24. package/components/chart/example-line-chart-with-custom-reference-line-value.njk +6 -3
  25. package/components/chart/example-line-chart-with-label-format.njk +6 -3
  26. package/components/chart/example-line-chart-with-markers.njk +6 -3
  27. package/components/chart/example-line-chart-with-range-annotations-inside.njk +6 -3
  28. package/components/chart/example-line-chart-with-range-annotations-outside-left-right.njk +6 -3
  29. package/components/chart/example-line-chart-with-range-annotations-outside-top-bottom.njk +6 -3
  30. package/components/chart/example-line-chart-with-reference-line-annotations.njk +6 -3
  31. package/components/chart/example-line-chart.njk +6 -3
  32. package/components/chart/example-scatter-chart-with-axis-min-and-max-values.njk +6 -3
  33. package/components/chart/example-scatter-chart.njk +6 -3
  34. package/components/chart/example-stacked-bar-chart.njk +6 -3
  35. package/components/chart/example-stacked-column-chart.njk +6 -3
  36. package/components/document-list/_macro.njk +2 -2
  37. package/components/document-list/_macro.spec.js +55 -0
  38. package/components/featured-article/_macro.njk +3 -37
  39. package/components/featured-article/example-featured-article-with-chart.njk +19 -14
  40. package/components/featured-article/example-featured-article-with-image.njk +12 -7
  41. package/components/featured-article/featured-article.scss +1 -1
  42. package/components/featured-article/macro.spec.js +44 -67
  43. package/components/figure/_figure.scss +31 -0
  44. package/components/figure/_macro.njk +98 -0
  45. package/components/figure/_macro.spec.js +520 -0
  46. package/components/figure/example-figure-heading-level-2.njk +34 -0
  47. package/components/figure/example-figure-with-div.njk +29 -0
  48. package/components/figure/example-figure-without-footer.njk +12 -0
  49. package/components/figure/example-figure-without-header.njk +24 -0
  50. package/components/figure/example-figure.njk +34 -0
  51. package/components/image/_image.scss +0 -7
  52. package/components/image/_macro.njk +25 -14
  53. package/components/image/_macro.spec.js +122 -7
  54. package/components/image/example-image-with-figure-fields.njk +25 -0
  55. package/components/list/_macro.njk +1 -0
  56. package/components/list/_macro.spec.js +16 -0
  57. package/components/table/_macro.njk +138 -111
  58. package/components/table/_macro.spec.js +172 -2
  59. package/components/table/_table.scss +6 -1
  60. package/components/table/example-table-with-figure-fields.njk +86 -0
  61. package/css/main.css +1 -1
  62. package/package.json +2 -2
  63. package/scss/main.scss +1 -0
@@ -1,17 +1,28 @@
1
1
  {%- macro onsImage(params) -%}
2
- <figure class="ons-image">
3
- {% if params.image %}
4
- <img
5
- class="ons-image__img"
6
- {% if params.image.largeSrc %}srcset="{{ params.image.smallSrc }} 1x, {{ params.image.largeSrc }} 2x"{% endif %}src="{{ params.image.smallSrc }}"
7
- alt="{{ params.alt if params.alt }}"
8
- />
9
- {% else %}
10
- <img class="ons-image__img" src="{{ params.src }}" alt="{{ params.alt }}" />
11
- {% endif %}
2
+ {% from "components/figure/_macro.njk" import onsFigure %}
12
3
 
13
- {% if params.caption %}
14
- <figcaption class="ons-image__caption">{{ params.caption }}</figcaption>
15
- {% endif %}
16
- </figure>
4
+ {%
5
+ call onsFigure({
6
+ "id": params.id,
7
+ "headingLevel": params.headingLevel,
8
+ "figureNumber": params.figureNumber,
9
+ "title": params.title,
10
+ "subtitle": params.subtitle,
11
+ "caption": params.caption,
12
+ "footnotes": params.footnotes,
13
+ "download": params.download
14
+ })
15
+ %}
16
+ <div class="ons-image">
17
+ {% if params.image %}
18
+ <img
19
+ class="ons-image__img"
20
+ {% if params.image.largeSrc %}srcset="{{ params.image.smallSrc }} 1x, {{ params.image.largeSrc }} 2x"{% endif %}src="{{ params.image.smallSrc }}"
21
+ alt="{{ params.alt if params.alt }}"
22
+ />
23
+ {% else %}
24
+ <img class="ons-image__img" src="{{ params.src }}" alt="{{ params.alt }}" />
25
+ {% endif %}
26
+ </div>
27
+ {% endcall %}
17
28
  {%- endmacro -%}
@@ -3,7 +3,7 @@
3
3
  import * as cheerio from 'cheerio';
4
4
 
5
5
  import axe from '../../tests/helpers/axe';
6
- import { renderComponent } from '../../tests/helpers/rendering';
6
+ import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
7
7
 
8
8
  const EXAMPLE_IMAGE_SRC_URL_MINIMAL = {
9
9
  src: 'example.png',
@@ -17,13 +17,14 @@ const EXAMPLE_IMAGE_IMAGE_MINIMAL = {
17
17
  };
18
18
 
19
19
  describe('macro: image', () => {
20
- it('outputs a `figure` element', () => {
20
+ it('outputs a `figure` element wrapping the image', () => {
21
21
  const $ = cheerio.load(renderComponent('image', EXAMPLE_IMAGE_SRC_URL_MINIMAL));
22
22
 
23
- expect($('.ons-image')[0].tagName).toBe('figure');
23
+ expect($('.ons-figure')[0].tagName).toBe('figure');
24
+ expect($('.ons-figure .ons-image').length).toBe(1);
24
25
  });
25
26
 
26
- it('outputs a `figurecaption` element when `caption` is provided', () => {
27
+ it('outputs a `figcaption` element when `caption` is provided', () => {
27
28
  const $ = cheerio.load(
28
29
  renderComponent('image', {
29
30
  ...EXAMPLE_IMAGE_SRC_URL_MINIMAL,
@@ -31,10 +32,10 @@ describe('macro: image', () => {
31
32
  }),
32
33
  );
33
34
 
34
- expect($('.ons-image__caption')[0].tagName).toBe('figcaption');
35
+ expect($('.ons-figure__caption')[0].tagName).toBe('figcaption');
35
36
  });
36
37
 
37
- it('outputs a `figurecaption` element with provided `caption` text', () => {
38
+ it('outputs a `figcaption` element with provided `caption` text', () => {
38
39
  const $ = cheerio.load(
39
40
  renderComponent('image', {
40
41
  ...EXAMPLE_IMAGE_SRC_URL_MINIMAL,
@@ -42,7 +43,121 @@ describe('macro: image', () => {
42
43
  }),
43
44
  );
44
45
 
45
- expect($('.ons-image__caption').text().trim()).toBe('Example image caption');
46
+ expect($('.ons-figure__caption').text().trim()).toBe('Example image caption');
47
+ });
48
+
49
+ describe('figure params', () => {
50
+ it('passes `id` to the figure component', () => {
51
+ const faker = templateFaker();
52
+ const figureSpy = faker.spy('figure');
53
+
54
+ faker.renderComponent('image', {
55
+ ...EXAMPLE_IMAGE_SRC_URL_MINIMAL,
56
+ id: 'my-image',
57
+ });
58
+
59
+ expect(figureSpy.occurrences[0].id).toBe('my-image');
60
+ });
61
+
62
+ it('passes `headingLevel` to the figure component', () => {
63
+ const faker = templateFaker();
64
+ const figureSpy = faker.spy('figure');
65
+
66
+ faker.renderComponent('image', {
67
+ ...EXAMPLE_IMAGE_SRC_URL_MINIMAL,
68
+ headingLevel: 4,
69
+ });
70
+
71
+ expect(figureSpy.occurrences[0].headingLevel).toBe(4);
72
+ });
73
+
74
+ it('passes `figureNumber` to the figure component', () => {
75
+ const faker = templateFaker();
76
+ const figureSpy = faker.spy('figure');
77
+
78
+ faker.renderComponent('image', {
79
+ ...EXAMPLE_IMAGE_SRC_URL_MINIMAL,
80
+ figureNumber: 'Image 1',
81
+ });
82
+
83
+ expect(figureSpy.occurrences[0].figureNumber).toBe('Image 1');
84
+ });
85
+
86
+ it('passes `title` to the figure component', () => {
87
+ const faker = templateFaker();
88
+ const figureSpy = faker.spy('figure');
89
+
90
+ faker.renderComponent('image', {
91
+ ...EXAMPLE_IMAGE_SRC_URL_MINIMAL,
92
+ title: 'Image title',
93
+ });
94
+
95
+ expect(figureSpy.occurrences[0].title).toBe('Image title');
96
+ });
97
+
98
+ it('passes `subtitle` to the figure component', () => {
99
+ const faker = templateFaker();
100
+ const figureSpy = faker.spy('figure');
101
+
102
+ faker.renderComponent('image', {
103
+ ...EXAMPLE_IMAGE_SRC_URL_MINIMAL,
104
+ subtitle: 'Image subtitle',
105
+ });
106
+
107
+ expect(figureSpy.occurrences[0].subtitle).toBe('Image subtitle');
108
+ });
109
+
110
+ it('passes `caption` to the figure component', () => {
111
+ const faker = templateFaker();
112
+ const figureSpy = faker.spy('figure');
113
+
114
+ faker.renderComponent('image', {
115
+ ...EXAMPLE_IMAGE_SRC_URL_MINIMAL,
116
+ caption: 'A caption',
117
+ });
118
+
119
+ expect(figureSpy.occurrences[0].caption).toBe('A caption');
120
+ });
121
+
122
+ it('passes `footnotes` to the figure component', () => {
123
+ const faker = templateFaker();
124
+ const figureSpy = faker.spy('figure');
125
+
126
+ const footnotes = {
127
+ title: 'Footnotes',
128
+ content: 'Some notes about this image.',
129
+ };
130
+
131
+ faker.renderComponent('image', {
132
+ ...EXAMPLE_IMAGE_SRC_URL_MINIMAL,
133
+ footnotes,
134
+ });
135
+
136
+ expect(figureSpy.occurrences[0].footnotes).toEqual(footnotes);
137
+ });
138
+
139
+ it('passes `download` to the figure component', () => {
140
+ const faker = templateFaker();
141
+ const figureSpy = faker.spy('figure');
142
+
143
+ const download = {
144
+ title: 'Download this image',
145
+ itemsList: [
146
+ {
147
+ text: 'High resolution image (JPG, 1.2MB)',
148
+ url: '/img/example.jpg',
149
+ download: 'file',
150
+ },
151
+ ],
152
+ };
153
+
154
+ faker.renderComponent('image', {
155
+ ...EXAMPLE_IMAGE_SRC_URL_MINIMAL,
156
+ download,
157
+ });
158
+
159
+ expect(figureSpy.occurrences[0].download).toEqual(download);
160
+ });
46
161
  });
47
162
 
48
163
  describe('mode: src', () => {
@@ -0,0 +1,25 @@
1
+ {% from "components/image/_macro.njk" import onsImage %}
2
+ {{
3
+ onsImage({
4
+ "id": "image-with-extra-fields",
5
+ "src": '/img/small/woman-in-purple-dress-shirt.jpg',
6
+ "alt": 'Woman in a purple dress shirt using a laptop',
7
+ "title": "Image 1: Working from home",
8
+ "subtitle": "A growing proportion of the workforce now works remotely",
9
+ "caption": "Image 1 - Woman in a purple dress shirt using a laptop",
10
+ "footnotes": {
11
+ "title": "Footnotes",
12
+ "content": "Image is for illustrative purposes only."
13
+ },
14
+ "download": {
15
+ "title": "Download this image",
16
+ "itemsList": [
17
+ {
18
+ "text": "High resolution image (JPG format, 1.2MB)",
19
+ "url": "/img/small/woman-in-purple-dress-shirt.jpg",
20
+ "download": "file"
21
+ }
22
+ ]
23
+ }
24
+ })
25
+ }}
@@ -79,6 +79,7 @@
79
79
  href="{{ item.url }}"
80
80
  class="ons-list__link{{ ' ons-js-inpagelink' if item.variants == 'inPageLink' }}{{ ' ' + item.classes if item.classes else '' }}"
81
81
  {% if item.target %}target="{{ item.target }}"{% endif %}
82
+ {% if item.download %}download="{{ item.download}}"{% endif %}
82
83
  >
83
84
  {%- if item.prefix -%}<span class="ons-u-vh">{{- item.prefix -}}</span>{%- endif -%} {{- itemText | safe -}}
84
85
  {%- if item.target == "_blank" -%}
@@ -376,6 +376,22 @@ describe('macro: list', () => {
376
376
  expect($('.ons-list__link').hasClass('another-extra-class')).toBe(true);
377
377
  });
378
378
 
379
+ it('has the provided `download` attribute', () => {
380
+ const $ = cheerio.load(
381
+ renderComponent('list', {
382
+ itemsList: [
383
+ {
384
+ ...item,
385
+ url: '/example.csv',
386
+ download: 'file',
387
+ },
388
+ ],
389
+ }),
390
+ );
391
+
392
+ expect($('.ons-list__link').attr('download')).toBe('file');
393
+ });
394
+
379
395
  it('has the provided `target` attribute', () => {
380
396
  const $ = cheerio.load(
381
397
  renderComponent('list', {
@@ -1,121 +1,148 @@
1
1
  {% macro onsTable(params) %}
2
2
  {% from "components/button/_macro.njk" import onsButton %}
3
3
  {% from "components/icon/_macro.njk" import onsIcon %}
4
+ {% from "components/figure/_macro.njk" import onsFigure %}
4
5
  {% set variants = params.variants if params.variants %}
5
6
 
6
- <div class="ons-table-scrollable ons-table-scrollable--on">
7
- <div
8
- class="ons-table-scrollable__content"
9
- tabindex="0"
10
- role="region"
11
- {% if params.ariaLabel %}aria-label="{{ params.ariaLabel }}"{% endif %}
12
- >
13
- {# Uses multiple loops to set the rowspan class so that it can work in both nunjucks and jinja2 environments due to the scoping rules of each language #}
14
- <table
15
- {% if params.id %}id="{{ params.id }}"{% endif %}
16
- class="ons-table{{ ' ' + params.tableClasses if params.tableClasses else '' }}{% for row in params.thList %}{% for th in row.ths %}{% if th.rowspan %}{{ ' ' }}ons-table--has-rowspan{% endif %}{% endfor %}{% endfor %}{% for row in params.trs %}{% for td in row.tds %}{% if td.rowspan %}{{ ' ' }}ons-table--has-rowspan{% endif %}{% endfor %}{% endfor %}{% if variants %}{% if variants is not string %}{% for variant in variants %}{{ ' ' }}ons-table--{{ variant }}{% endfor %}{% else %}{{ ' ' }}ons-table--{{ variants }}{% endif %}{% endif %}"
17
- {% if params.sortBy and 'sortable' in variants %}
18
- data-aria-sort="{{ params.sortBy }}" data-aria-asc="{{ params.ariaAsc }}" data-aria-desc="{{ params.ariaDesc }}"
19
- {% endif %}
7
+ {%
8
+ call onsFigure({
9
+ "useDivForRootElement": true,
10
+ "id": params.id,
11
+ "headingLevel": params.headingLevel,
12
+ "figureNumber": params.figureNumber,
13
+ "title": params.title,
14
+ "subtitle": params.subtitle,
15
+ "footnotes": params.footnotes,
16
+ "download": params.download,
17
+ "caption": params.sourceNote
18
+ })
19
+ %}
20
+ {% set tableClasses = "ons-table" %}
21
+
22
+ {# If there is no source note, footnotes or downloads after the table, add a bottom margin to the table to match the previous spacing #}
23
+ {# If there source note, footnotes or downloads after the table, the figure component handles the extra spacing #}
24
+ {% if not params.sourceNote and not params.footnotes and not params.download %}
25
+ {% set tableClasses = tableClasses + " ons-table--bottom-space" %}
26
+ {% endif %}
27
+
28
+ {% if params.tableClasses %}
29
+ {% set tableClasses = tableClasses + " " + params.tableClasses %}
30
+ {% endif %}
31
+
32
+ <div class="ons-table-scrollable ons-table-scrollable--on">
33
+ <div
34
+ class="ons-table-scrollable__content"
35
+ tabindex="0"
36
+ role="region"
37
+ {% if params.ariaLabel %}aria-label="{{ params.ariaLabel }}"{% endif %}
20
38
  >
21
- {% if params.caption %}
22
- <caption class="ons-table__caption{{ ' ons-u-vh' if params.hideCaption }}">
23
- {{ params.caption }}
24
- </caption>
25
- {% endif %}
26
- <thead class="ons-table__head">
27
- {# Uses thList if multiple-row headers, otherwise wrap single ths array into a default group #}
28
- {% if params.thList %}
29
- {% set thGroups = params.thList %}
30
- {% else %}
31
- {% set thGroups = [ { "ths": params.ths } ] %}
39
+ {# Uses multiple loops to set the rowspan class so that it can work in both nunjucks and jinja2 environments due to the scoping rules of each language #}
40
+ <table
41
+ class="{{ tableClasses }}{% for row in params.thList %}{% for th in row.ths %}{% if th.rowspan %}{{ ' ' }}ons-table--has-rowspan{% endif %}{% endfor %}{% endfor %}{% for row in params.trs %}{% for td in row.tds %}{% if td.rowspan %}{{ ' ' }}ons-table--has-rowspan{% endif %}{% endfor %}{% endfor %}{% if variants %}{% if variants is not string %}{% for variant in variants %}{{ ' ' }}ons-table--{{ variant }}{% endfor %}{% else %}{{ ' ' }}ons-table--{{ variants }}{% endif %}{% endif %}"
42
+ {% if params.sortBy and 'sortable' in variants %}
43
+ data-aria-sort="{{ params.sortBy }}" data-aria-asc="{{ params.ariaAsc }}" data-aria-desc="{{ params.ariaDesc }}"
32
44
  {% endif %}
33
- {% for headerCols in thGroups %}
34
- <tr class="ons-table__row">
35
- {% for th in headerCols.ths %}
36
- <th
37
- scope="col"
38
- class="ons-table__header ons-table__header--{{ th.valign | default('top') }}{{ ' ' + th.thClasses if th.thClasses else '' }}{{ ' ons-table__header--numeric' if th.numeric }}"
39
- {% if th.colspan %}colspan="{{ th.colspan }}"{% endif %}
40
- {% if th.rowspan %}rowspan="{{ th.rowspan }}"{% endif %}
41
- {% if 'sortable' in variants %}aria-sort="{{ th.ariaSort | default('none') }}"{% endif %}
42
- {% if th.widthPercentage %}width="{{ th.widthPercentage }}%"{% endif %}
43
- >
44
- <span class="ons-table__header-text">{{ th.value | safe }}</span>
45
- {% if 'sortable' in variants %}
46
- {{-
47
- onsIcon({
48
- "iconType": "sort-sprite",
49
- "id": th.value | replace(' ', '-'),
50
- "classes": 'ons-u-d-no'
51
- })
52
- -}}
53
- {% endif %}
54
- </th>
55
- {% endfor %}
56
- </tr>
57
- {% endfor %}
58
- </thead>
59
- <tbody class="ons-table__body">
60
- {% for tr in params.trs %}
61
- <tr
62
- class="ons-table__row{{ ' ons-table__row--highlight' if tr.highlight }}"
63
- {% if tr.id %}id="{{ tr.id }}"{% endif %}
64
- >
65
- {% for td in tr.tds %}
66
- {% if td.heading == true %}
67
- {% set openingTag = '<th' %}
68
- {% set closingTag = '</th>' %}
69
- {% else %}
70
- {% set openingTag = '<td' %}
71
- {% set closingTag = '</td>' %}
72
- {% endif %}
73
- {% set isFirstRow = loop.index == 0 and td.rowspan %}
74
- {% set rowSpan = isFirstRow and loop.index0 == rowspanCount %}
75
- {{ openingTag | safe }}
76
- class="ons-table__cell
77
- ons-table__cell--{{ td.valign | default('top') }}{{ ' ' + td.tdClasses if td.tdClasses else '' }}{{ ' ons-table__cell--numeric' if td.numeric }}"
78
- {% if td.id %}id="{{ td.id }}"{% endif %}
79
- {% if td.data %}{{ ' ' }}data-th="{{ td.data }}"{% endif %}
80
- {% if td.colspan %}colspan="{{ td.colspan }}"{% endif %}
81
- {% if td.rowspan %}rowspan="{{ td.rowspan }}"{% endif %}
82
- {% if td.dataSort %}{{ ' ' }}data-sort-value="{{ td.dataSort }}"{% endif %}
83
- {% if td.heading %}scope="row"{% endif %}
84
- >
85
- {% if td.form %}
86
- <form action="{{ td.form.action }}" method="{{ td.form.method | default('POST') }}">
87
- {{ onsButton(td.form.button) }}
88
- {% if td.form.hiddenFormField %}
89
- {% for hiddenField in td.form.hiddenFormField %}
90
- <input
91
- type="hidden"
92
- {% if hiddenField.name %}name="{{ hiddenField.name }}"{% endif %}
93
- {% if hiddenField.value %}value="{{ hiddenField.value }}"{% endif %}
94
- />
95
- {% endfor %}
45
+ >
46
+ {# Note that the caption is rendered inside the table element to be semantically correct, and we deliberately do not render it with the onsFigure caption option. We also have the option to visually hide it for the table. #}
47
+ {% if params.caption %}
48
+ <caption class="ons-table__caption{{ ' ons-u-vh' if params.hideCaption }}">
49
+ {{ params.caption }}
50
+ </caption>
51
+ {% endif %}
52
+ <thead class="ons-table__head">
53
+ {# Uses thList if multiple-row headers, otherwise wrap single ths array into a default group #}
54
+ {% if params.thList %}
55
+ {% set thGroups = params.thList %}
56
+ {% else %}
57
+ {% set thGroups = [ { "ths": params.ths } ] %}
58
+ {% endif %}
59
+ {% for headerCols in thGroups %}
60
+ <tr class="ons-table__row">
61
+ {% for th in headerCols.ths %}
62
+ <th
63
+ scope="col"
64
+ class="ons-table__header ons-table__header--{{ th.valign | default('top') }}{{ ' ' + th.thClasses if th.thClasses else '' }}{{ ' ons-table__header--numeric' if th.numeric }}"
65
+ {% if th.colspan %}colspan="{{ th.colspan }}"{% endif %}
66
+ {% if th.rowspan %}rowspan="{{ th.rowspan }}"{% endif %}
67
+ {% if 'sortable' in variants %}aria-sort="{{ th.ariaSort | default('none') }}"{% endif %}
68
+ {% if th.widthPercentage %}width="{{ th.widthPercentage }}%"{% endif %}
69
+ >
70
+ <span class="ons-table__header-text">{{ th.value | safe }}</span>
71
+ {% if 'sortable' in variants %}
72
+ {{-
73
+ onsIcon({
74
+ "iconType": "sort-sprite",
75
+ "id": th.value | replace(' ', '-'),
76
+ "classes": 'ons-u-d-no'
77
+ })
78
+ -}}
96
79
  {% endif %}
97
- </form>
98
- {% endif %}
99
- {% if td.value %}
100
- {{ td.value | safe }}
101
- {% endif %}
102
- {{ closingTag | safe }}
103
- {% endfor %}
104
- </tr>
105
- {% endfor %}
106
- </tbody>
107
- {% if params.tfoot %}
108
- <tfoot class="ons-table__foot">
109
- <tr class="ons-table__row">
110
- {% for tfootCell in params.tfoot %}
111
- <td class="ons-table__cell ons-table__cell--{{ tfootCell.valign | default('top') }} ons-u-fs-s">
112
- {{ tfootCell.value }}
113
- </td>
114
- {% endfor %}
115
- </tr>
116
- </tfoot>
117
- {% endif %}
118
- </table>
80
+ </th>
81
+ {% endfor %}
82
+ </tr>
83
+ {% endfor %}
84
+ </thead>
85
+ <tbody class="ons-table__body">
86
+ {% for tr in params.trs %}
87
+ <tr
88
+ class="ons-table__row{{ ' ons-table__row--highlight' if tr.highlight }}"
89
+ {% if tr.id %}id="{{ tr.id }}"{% endif %}
90
+ >
91
+ {% for td in tr.tds %}
92
+ {% if td.heading == true %}
93
+ {% set openingTag = '<th' %}
94
+ {% set closingTag = '</th>' %}
95
+ {% else %}
96
+ {% set openingTag = '<td' %}
97
+ {% set closingTag = '</td>' %}
98
+ {% endif %}
99
+ {% set isFirstRow = loop.index == 0 and td.rowspan %}
100
+ {% set rowSpan = isFirstRow and loop.index0 == rowspanCount %}
101
+ {{ openingTag | safe }}
102
+ class="ons-table__cell
103
+ ons-table__cell--{{ td.valign | default('top') }}{{ ' ' + td.tdClasses if td.tdClasses else '' }}{{ ' ons-table__cell--numeric' if td.numeric }}"
104
+ {% if td.id %}id="{{ td.id }}"{% endif %}
105
+ {% if td.data %}{{ ' ' }}data-th="{{ td.data }}"{% endif %}
106
+ {% if td.colspan %}colspan="{{ td.colspan }}"{% endif %}
107
+ {% if td.rowspan %}rowspan="{{ td.rowspan }}"{% endif %}
108
+ {% if td.dataSort %}{{ ' ' }}data-sort-value="{{ td.dataSort }}"{% endif %}
109
+ {% if td.heading %}scope="row"{% endif %}
110
+ >
111
+ {% if td.form %}
112
+ <form action="{{ td.form.action }}" method="{{ td.form.method | default('POST') }}">
113
+ {{ onsButton(td.form.button) }}
114
+ {% if td.form.hiddenFormField %}
115
+ {% for hiddenField in td.form.hiddenFormField %}
116
+ <input
117
+ type="hidden"
118
+ {% if hiddenField.name %}name="{{ hiddenField.name }}"{% endif %}
119
+ {% if hiddenField.value %}value="{{ hiddenField.value }}"{% endif %}
120
+ />
121
+ {% endfor %}
122
+ {% endif %}
123
+ </form>
124
+ {% endif %}
125
+ {% if td.value %}
126
+ {{ td.value | safe }}
127
+ {% endif %}
128
+ {{ closingTag | safe }}
129
+ {% endfor %}
130
+ </tr>
131
+ {% endfor %}
132
+ </tbody>
133
+ {% if params.tfoot %}
134
+ <tfoot class="ons-table__foot">
135
+ <tr class="ons-table__row">
136
+ {% for tfootCell in params.tfoot %}
137
+ <td class="ons-table__cell ons-table__cell--{{ tfootCell.valign | default('top') }} ons-u-fs-s">
138
+ {{ tfootCell.value }}
139
+ </td>
140
+ {% endfor %}
141
+ </tr>
142
+ </tfoot>
143
+ {% endif %}
144
+ </table>
145
+ </div>
119
146
  </div>
120
- </div>
147
+ {% endcall %}
121
148
  {% endmacro %}