@ons/design-system 72.10.4 → 72.10.6

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 (39) hide show
  1. package/components/button/_button.scss +8 -6
  2. package/components/chart/_chart.scss +2 -14
  3. package/components/chart/_macro.njk +15 -3
  4. package/components/chart/_macro.spec.js +163 -1
  5. package/components/chart/boxplot.js +3 -0
  6. package/components/chart/columnrange-chart.js +3 -0
  7. package/components/chart/example-area-chart-with-axis-min-and-max-values.njk +72 -0
  8. package/components/chart/example-bar-chart-with-axis-min-and-max-values.njk +59 -0
  9. package/components/chart/example-column-chart-with-axis-min-and-max-values.njk +59 -0
  10. package/components/chart/example-line-chart-with-axis-min-and-max-values.njk +227 -0
  11. package/components/chart/example-scatter-chart-with-axis-min-and-max-values.njk +98 -0
  12. package/components/chart/specific-chart-options.js +29 -6
  13. package/components/details-panel/_details-panel.scss +4 -0
  14. package/components/details-panel/_macro.njk +17 -13
  15. package/components/details-panel/_macro.spec.js +17 -0
  16. package/components/details-panel/example-details-panel-open.njk +2 -1
  17. package/components/details-panel/example-details-panel.njk +2 -1
  18. package/components/header/_header.scss +40 -24
  19. package/components/header/_macro.njk +103 -89
  20. package/components/header/_macro.spec.js +131 -3
  21. package/components/header/example-header-basic-with-search-and-language.njk +207 -0
  22. package/components/header/{example-header-with-search-button.njk → example-header-basic-with-search-button.njk} +1 -0
  23. package/components/header/example-header-basic.njk +1 -0
  24. package/components/hero/_macro.njk +9 -2
  25. package/components/hero/_macro.spec.js +22 -0
  26. package/components/hero/example-hero-grey.njk +2 -1
  27. package/components/language-selector/_macro.njk +1 -1
  28. package/components/language-selector/_macro.spec.js +49 -3
  29. package/components/navigation/navigation.js +24 -17
  30. package/components/pagination/_macro.njk +17 -7
  31. package/components/pagination/_macro.spec.js +191 -17
  32. package/components/table/_macro.njk +83 -44
  33. package/components/table/_macro.spec.js +90 -0
  34. package/components/table/_table.scss +15 -3
  35. package/components/table/example-table-merge-cells.njk +139 -0
  36. package/css/main.css +1 -1
  37. package/package.json +1 -1
  38. package/scripts/main.es5.js +1 -1
  39. package/scripts/main.js +1 -1
@@ -2,11 +2,27 @@
2
2
  {% from "components/button/_macro.njk" import onsButton %}
3
3
  {% from "components/icon/_macro.njk" import onsIcon %}
4
4
  {% set variants = params.variants if params.variants %}
5
+ {% set hasRowSpan = false %}
6
+ {% for row in params.thList %}
7
+ {% for th in row.ths %}
8
+ {% if th.rowspan %}
9
+ {% set hasRowSpan = true %}
10
+ {% endif %}
11
+ {% endfor %}
12
+ {% endfor %}
13
+
14
+ {% for row in params.trs %}
15
+ {% for td in row.tds %}
16
+ {% if td.rowspan %}
17
+ {% set hasRowSpan = true %}
18
+ {% endif %}
19
+ {% endfor %}
20
+ {% endfor %}
5
21
 
6
22
  {% set table %}
7
23
  <table
8
24
  {% if params.id %}id="{{ params.id }}"{% endif %}
9
- class="ons-table{{ ' ' + params.tableClasses if params.tableClasses else '' }}{% if variants and variants is not string %}{% for variant in variants %}{{ ' ' }}ons-table--{{ variant }}{% endfor %}{% else %}{{ ' ' }}ons-table--{{ variants }}{% endif %}"
25
+ class="ons-table{{ ' ' + params.tableClasses if params.tableClasses else '' }}{% if hasRowSpan %}{{ ' ' }}ons-table--has-rowspan{% endif %}{% if variants %}{% if variants is not string %}{% for variant in variants %}{{ ' ' }}ons-table--{{ variant }}{% endfor %}{% else %}{{ ' ' }}ons-table--{{ variants }}{% endif %}{% endif %}"
10
26
  {% if params.sortBy and 'sortable' in variants %}
11
27
  data-aria-sort="{{ params.sortBy }}" data-aria-asc="{{ params.ariaAsc }}" data-aria-desc="{{ params.ariaDesc }}"
12
28
  {% endif %}
@@ -17,55 +33,78 @@
17
33
  </caption>
18
34
  {% endif %}
19
35
  <thead class="ons-table__head">
20
- <tr class="ons-table__row">
21
- {% for th in params.ths %}
22
- <th
23
- scope="col"
24
- class="ons-table__header{{ ' ' + th.thClasses if th.thClasses else '' }}{{ ' ons-table__header--numeric'if th.numeric }}"
25
- {% if 'sortable' in variants %}aria-sort="{{- th.ariaSort | default('none') -}}"{% endif %}{% if th.widthPercentage %}width="{{ th.widthPercentage }}%"{% endif %}
26
- >
27
- <span class="ons-table__header-text">{{- th.value -}}</span>
28
- {% if 'sortable' in variants %}
29
- {{-
30
- onsIcon({
31
- "iconType": "sort-sprite",
32
- "id": th.value | replace(' ', '-'),
33
- "classes": 'ons-u-d-no'
34
- })
35
- -}}
36
- {% endif %}
37
- </th>
38
- {% endfor %}
39
- </tr>
36
+ {# Uses thList if multiple-row headers, otherwise wrap single ths array into a default group #}
37
+ {% if params.thList %}
38
+ {% set thGroups = params.thList %}
39
+ {% else %}
40
+ {% set thGroups = [ { ths: params.ths } ] %}
41
+ {% endif %}
42
+ {% for headerCols in thGroups %}
43
+ <tr class="ons-table__row">
44
+ {% for th in headerCols.ths %}
45
+ <th
46
+ scope="col"
47
+ class="ons-table__header{{ ' ' + th.thClasses if th.thClasses else '' }}{{ ' ons-table__header--numeric' if th.numeric }}"
48
+ {% if th.colspan %}colspan="{{ th.colspan }}"{% endif %}
49
+ {% if th.rowspan %}rowspan="{{ th.rowspan }}"{% endif %}
50
+ {% if 'sortable' in variants %}aria-sort="{{ th.ariaSort | default('none') }}"{% endif %}
51
+ {% if th.widthPercentage %}width="{{ th.widthPercentage }}%"{% endif %}
52
+ >
53
+ <span class="ons-table__header-text">{{ th.value | safe }}</span>
54
+ {% if 'sortable' in variants %}
55
+ {{-
56
+ onsIcon({
57
+ "iconType": "sort-sprite",
58
+ "id": th.value | replace(' ', '-'),
59
+ "classes": 'ons-u-d-no'
60
+ })
61
+ -}}
62
+ {% endif %}
63
+ </th>
64
+ {% endfor %}
65
+ </tr>
66
+ {% endfor %}
40
67
  </thead>
41
68
  <tbody class="ons-table__body">
42
69
  {% for tr in params.trs %}
43
70
  <tr class="ons-table__row{{ ' ons-table__row--highlight' if tr.highlight }}" {% if tr.id %}id="{{ tr.id }}"{% endif %}>
44
71
  {% for td in tr.tds %}
45
- <td
46
- class="ons-table__cell{{ ' ' + td.tdClasses if td.tdClasses else '' }}{{ ' ons-table__cell--numeric' if td.numeric }}"
47
- {% if td.id %}id="{{ td.id }}"{% endif %}
48
- {% if td.data %}{{ ' ' }}data-th="{{ td.data }}"{% endif %}
49
- {% if td.dataSort %}{{ ' ' }}data-sort-value="{{ td.dataSort }}"{% endif %}
72
+ {% if td.heading == true %}
73
+ {% set openingTag = '<th' %}
74
+ {% set closingTag = '</th>' %}
75
+ {% else %}
76
+ {% set openingTag = '<td' %}
77
+ {% set closingTag = '</td>' %}
78
+ {% endif %}
79
+ {% set isFirstRow = loop.index == 0 and td.rowspan %}
80
+ {% set rowSpan = isFirstRow and loop.index0 == rowspanCount %}
81
+ {{ openingTag | safe }}
82
+ class="ons-table__cell{{ ' ' + td.tdClasses if td.tdClasses else '' }}{{ ' ons-table__cell--numeric' if td.numeric }}"
83
+ {% if td.id %}id="{{ td.id }}"{% endif %}
84
+ {% if td.data %}{{ ' ' }}data-th="{{ td.data }}"{% endif %}
85
+ {% if td.colspan %}colspan="{{ td.colspan }}"{% endif %}
86
+ {% if td.rowspan %}rowspan="{{ td.rowspan }}"{% endif %}
87
+ {% if td.dataSort %}{{ ' ' }}data-sort-value="{{ td.dataSort }}"{% endif %}
88
+ {% if td.heading %}scope="row"{% endif %}
50
89
  >
51
- {% if td.form %}
52
- <form action="{{ td.form.action }}" method="{{ td.form.method | default('POST') }}">
53
- {{ onsButton(td.form.button) }}
54
- {% if td.form.hiddenFormField %}
55
- {% for hiddenField in td.form.hiddenFormField %}
56
- <input
57
- type="hidden"
58
- {% if hiddenField.name %}name="{{ hiddenField.name }}"{% endif %}
59
- {% if hiddenField.value %}value="{{ hiddenField.value }}"{% endif %}
60
- />
61
- {% endfor %}
62
- {% endif %}
63
- </form>
64
- {% endif %}
65
- {% if td.value %}
66
- {{ td.value | safe }}
67
- {% endif %}
68
- </td>
90
+ {% if td.form %}
91
+ <form action="{{ td.form.action }}" method="{{ td.form.method | default('POST') }}">
92
+ {{ onsButton(td.form.button) }}
93
+ {% if td.form.hiddenFormField %}
94
+ {% for hiddenField in td.form.hiddenFormField %}
95
+ <input
96
+ type="hidden"
97
+ {% if hiddenField.name %}name="{{ hiddenField.name }}"{% endif %}
98
+ {% if hiddenField.value %}value="{{ hiddenField.value }}"{% endif %}
99
+ />
100
+ {% endfor %}
101
+ {% endif %}
102
+ </form>
103
+ {% endif %}
104
+ {% if td.value %}
105
+ {{ td.value | safe }}
106
+ {% endif %}
107
+ {{ closingTag | safe }}
69
108
  {% endfor %}
70
109
  </tr>
71
110
  {% endfor %}
@@ -95,6 +95,36 @@ describe('macro: table', () => {
95
95
 
96
96
  expect($('.ons-table__header').attr('width')).toBe('50%');
97
97
  });
98
+ it('adds additional colspan attribute to column header', () => {
99
+ const $ = cheerio.load(
100
+ renderComponent('table', {
101
+ ...EXAMPLE_TABLE,
102
+ ths: [
103
+ {
104
+ value: 'Column 1',
105
+ colspan: 2,
106
+ },
107
+ ],
108
+ }),
109
+ );
110
+
111
+ expect($('.ons-table__header').attr('colspan')).toBe('2');
112
+ });
113
+ it('adds additional rowspan attribute to column header', () => {
114
+ const $ = cheerio.load(
115
+ renderComponent('table', {
116
+ ...EXAMPLE_TABLE,
117
+ ths: [
118
+ {
119
+ value: 'Column 1',
120
+ rowspan: 2,
121
+ },
122
+ ],
123
+ }),
124
+ );
125
+
126
+ expect($('.ons-table__header').attr('rowspan')).toBe('2');
127
+ });
98
128
 
99
129
  it('does not add "numeric" modifier class to column header when `td.numeric` is not provided', () => {
100
130
  const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
@@ -135,6 +165,28 @@ describe('macro: table', () => {
135
165
  });
136
166
  });
137
167
 
168
+ describe('Multiple Header Rows', () => {
169
+ it('renders expected header row cells', () => {
170
+ const $ = cheerio.load(
171
+ renderComponent('table', {
172
+ ...EXAMPLE_TABLE,
173
+ thList: [
174
+ {
175
+ ths: [{ value: 'Column 1' }, { value: 'Column 2' }],
176
+ },
177
+ {
178
+ ths: [{ value: 'Column A' }, { value: 'Column B' }],
179
+ },
180
+ ],
181
+ }),
182
+ );
183
+ const row1Values = mapAll($('.ons-table__row:nth-child(1) .ons-table__header'), (node) => node.text().trim());
184
+ expect(row1Values).toEqual(['Column 1', 'Column 2']);
185
+ const row2Values = mapAll($('.ons-table__row:nth-child(2) .ons-table__header'), (node) => node.text().trim());
186
+ expect(row2Values).toEqual(['Column A', 'Column B']);
187
+ });
188
+ });
189
+
138
190
  describe('row', () => {
139
191
  it('renders expected row cells', () => {
140
192
  const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
@@ -291,6 +343,44 @@ describe('macro: table', () => {
291
343
 
292
344
  expect($('.ons-table__cell').hasClass('ons-table__cell--numeric')).toBe(true);
293
345
  });
346
+ it('adds additional colspan attribute to row header', () => {
347
+ const $ = cheerio.load(
348
+ renderComponent('table', {
349
+ ...EXAMPLE_TABLE,
350
+ trs: [
351
+ {
352
+ tds: [
353
+ {
354
+ value: 'Column 1',
355
+ colspan: 2,
356
+ },
357
+ ],
358
+ },
359
+ ],
360
+ }),
361
+ );
362
+
363
+ expect($('.ons-table__cell').attr('colspan')).toBe('2');
364
+ });
365
+ it('adds additional rowspan attribute to row header', () => {
366
+ const $ = cheerio.load(
367
+ renderComponent('table', {
368
+ ...EXAMPLE_TABLE,
369
+ trs: [
370
+ {
371
+ tds: [
372
+ {
373
+ value: 'Column 1',
374
+ rowspan: 2,
375
+ },
376
+ ],
377
+ },
378
+ ],
379
+ }),
380
+ );
381
+
382
+ expect($('.ons-table__cell').attr('rowspan')).toBe('2');
383
+ });
294
384
 
295
385
  describe('form', () => {
296
386
  const params = {
@@ -13,10 +13,15 @@
13
13
  text-align: left;
14
14
  }
15
15
 
16
+ &__row:not(.ons-table__row--after-rowspan) {
17
+ .ons-table__cell,
18
+ .ons-table__header {
19
+ @include nth-element(1, 0);
20
+ }
21
+ }
22
+
16
23
  &__header,
17
24
  &__cell {
18
- @include nth-element(1, 0);
19
-
20
25
  border-bottom: 2px solid var(--ons-color-grey-75);
21
26
  overflow: hidden;
22
27
  padding: 0.5rem 0 0.5rem 1rem;
@@ -27,6 +32,13 @@
27
32
  }
28
33
  }
29
34
 
35
+ &--has-rowspan {
36
+ .ons-table__header,
37
+ .ons-table__cell {
38
+ padding: 0.5rem 1.5rem 0.5rem 0;
39
+ }
40
+ }
41
+
30
42
  &__cell,
31
43
  &__header--row {
32
44
  border-bottom: 1px solid var(--ons-color-borders);
@@ -36,7 +48,7 @@
36
48
  background: var(--ons-color-highlight);
37
49
  }
38
50
 
39
- &:not(.ons-table--responsive) .ons-table__body .ons-table__row:last-child {
51
+ &:not(.ons-table--responsive, .ons-table--has-rowspan) .ons-table__body .ons-table__row:last-child {
40
52
  .ons-table__cell,
41
53
  .ons-table__header--row {
42
54
  border: 0;
@@ -0,0 +1,139 @@
1
+ {% from "components/table/_macro.njk" import onsTable %}
2
+ {{
3
+ onsTable({
4
+ "caption": "Table with cells merged, multiple row headers and column headers",
5
+ "id": "basic-table",
6
+ "ths": [
7
+ {
8
+ "value": "Trade Category"
9
+ },
10
+ {
11
+ "value": "Metrics"
12
+ },
13
+ {
14
+ "value": "Exports"
15
+ },
16
+ {
17
+ "value": "Imports"
18
+ },
19
+ {
20
+ "value": "Balance"
21
+ }
22
+
23
+ ],
24
+ "trs": [
25
+ {
26
+ "tds": [
27
+ {
28
+ "heading": true,
29
+ "value": "Total trade in goods: December 2024 vs November 2024",
30
+ "rowspan":3
31
+ },
32
+ {
33
+ "heading": true,
34
+ "value": "Value (£bn)"
35
+ },
36
+ {
37
+ "value": "28.8"
38
+ },
39
+ {
40
+ "value": "45.7"
41
+ },
42
+ {
43
+ "value": "-16.9"
44
+ }
45
+ ]
46
+ },
47
+ {
48
+ "tds": [
49
+ {
50
+ "heading": true,
51
+ "value": "Change (£bn)"
52
+ },
53
+ {
54
+ "value": "0.0"
55
+ },
56
+ {
57
+ "value": "-1.2"
58
+ },
59
+ {
60
+ "value": "1.2"
61
+ }
62
+ ]
63
+ },
64
+ {
65
+ "tds": [
66
+ {
67
+ "heading": true,
68
+ "value": "%Change"
69
+ },
70
+ {
71
+ "value": "0.0"
72
+ },
73
+ {
74
+ "value": "2.6"
75
+ },
76
+ {
77
+ "value": ""
78
+ }
79
+ ]
80
+ },
81
+ {
82
+ "tds": [
83
+ {
84
+ "heading": true,
85
+ "value": "EU: December 2024 vs November 2024",
86
+ "rowspan": 3
87
+ },
88
+ {
89
+ "value": "Value (£bn)",
90
+ "heading": true
91
+ },
92
+ {
93
+ "value": "13.6"
94
+ },
95
+ {
96
+ "value": "24.9"
97
+ },
98
+ {
99
+ "value": "-11.3"
100
+ }
101
+ ]
102
+ },
103
+ {
104
+ "tds": [
105
+ {
106
+ "value": "Change (£bn)",
107
+ "heading": true
108
+ },
109
+ {
110
+ "value": "-0.5"
111
+ },
112
+ {
113
+ "value": "-0.8"
114
+ },
115
+ {
116
+ "value": "0.3"
117
+ }
118
+ ]
119
+ },
120
+ {
121
+ "tds": [
122
+ {
123
+ "heading": true,
124
+ "value": "%Change"
125
+ },
126
+ {
127
+ "value": "3.5"
128
+ },
129
+ {
130
+ "value": "-1.8"
131
+ },
132
+ {
133
+ "value": ""
134
+ }
135
+ ]
136
+ }
137
+ ]
138
+ })
139
+ }}