@ons/design-system 72.10.2 → 72.10.4

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 (38) hide show
  1. package/components/card/_card.scss +1 -0
  2. package/components/card/example-card-set-with-headline-figures.njk +4 -4
  3. package/components/chart/_macro.njk +34 -34
  4. package/components/chart/_macro.spec.js +0 -49
  5. package/components/chart/bar-chart.js +0 -2
  6. package/components/chart/chart.js +28 -17
  7. package/components/chart/columnrange-chart.js +3 -0
  8. package/components/chart/common-chart-options.js +1 -128
  9. package/components/chart/example-bar-with-confidence-levels.njk +0 -5
  10. package/components/chart/example-column-with-confidence-levels.njk +1 -4
  11. package/components/chart/example-scatter-chart.njk +4 -8
  12. package/components/chart/specific-chart-options.js +141 -1
  13. package/components/description-list/_description-list.scss +7 -6
  14. package/components/description-list/_macro.njk +1 -1
  15. package/components/details-panel/_details-panel.scss +40 -20
  16. package/components/details-panel/_macro.njk +18 -12
  17. package/components/details-panel/example-details-panel.njk +1 -0
  18. package/components/featured-article/_macro.njk +76 -0
  19. package/components/featured-article/example-featured-article-with-chart.njk +223 -0
  20. package/components/featured-article/example-featured-article-with-image.njk +24 -0
  21. package/components/featured-article/featured-article.scss +33 -0
  22. package/components/featured-article/macro.spec.js +173 -0
  23. package/components/header/_header.scss +34 -1
  24. package/components/header/_macro.njk +140 -132
  25. package/components/hero/_hero.scss +5 -0
  26. package/components/hero/_macro.njk +8 -4
  27. package/components/hero/example-hero-grey.njk +2 -17
  28. package/css/main.css +1 -1
  29. package/css/print.css +1 -1
  30. package/js/details.js +39 -0
  31. package/js/main.js +1 -0
  32. package/package.json +1 -1
  33. package/scripts/main.es5.js +1 -1
  34. package/scripts/main.js +1 -1
  35. package/scss/main.scss +1 -0
  36. package/scss/objects/_page.scss +1 -1
  37. package/scss/print.scss +6 -1
  38. package/scss/utilities/_grid.scss +46 -0
@@ -2,7 +2,7 @@ import ChartConstants from './chart-constants';
2
2
 
3
3
  // Options that rely on the chart config but are not specific to the chart type
4
4
  class SpecificChartOptions {
5
- constructor(theme, type, config) {
5
+ constructor(theme, type, config, xAxisTickInterval, yAxisTickInterval) {
6
6
  this.constants = ChartConstants.constants();
7
7
  this.theme = theme;
8
8
  this.config = config;
@@ -13,11 +13,77 @@ class SpecificChartOptions {
13
13
  type: type,
14
14
  marginTop: this.config.legend.enabled ? (type === 'boxplot' ? 50 : undefined) : 50,
15
15
  },
16
+ yAxis: {
17
+ tickInterval: yAxisTickInterval,
18
+ },
19
+ xAxis: {
20
+ tickInterval: xAxisTickInterval,
21
+ },
16
22
  };
17
23
  }
18
24
 
19
25
  getOptions = () => this.options;
20
26
 
27
+ getMobileOptions = (xAxisTickInterval, yAxisTickInterval) => {
28
+ return {
29
+ tooltip: {
30
+ enabled: false,
31
+ },
32
+ xAxis: {
33
+ tickInterval: xAxisTickInterval,
34
+ },
35
+ yAxis: {
36
+ tickInterval: yAxisTickInterval,
37
+ },
38
+ };
39
+ };
40
+
41
+ hideDataLabels = (series) => {
42
+ series.forEach((series) => {
43
+ series.update({
44
+ dataLabels: {
45
+ enabled: false,
46
+ },
47
+ });
48
+ });
49
+ };
50
+
51
+ disableLegendForSingleSeries = (config) => {
52
+ if (config.chart.type != 'boxplot' && config.series.length === 1) {
53
+ config.legend = {
54
+ enabled: false,
55
+ };
56
+ config.chart.marginTop = 50;
57
+ }
58
+ };
59
+
60
+ adjustChartHeight = (currentChart, percentageHeightDesktop, percentageHeightMobile) => {
61
+ // get current width of the plot area
62
+ const plotWidth = currentChart.plotWidth;
63
+ let newPlotHeight = undefined;
64
+ let totalHeight = 400; // Highcharts default height - needed if one of the percentage heights is undefined
65
+
66
+ // Calculate the new plot height based on the percentage height
67
+ if (plotWidth > 400) {
68
+ if (percentageHeightDesktop !== undefined) {
69
+ newPlotHeight = Math.round(plotWidth * (percentageHeightDesktop / 100));
70
+ }
71
+ } else {
72
+ if (percentageHeightMobile !== undefined) {
73
+ newPlotHeight = Math.round(plotWidth * (percentageHeightMobile / 100));
74
+ }
75
+ }
76
+ // update the total height if we have a new plot height
77
+ if (newPlotHeight !== undefined) {
78
+ totalHeight = currentChart.plotTop + newPlotHeight + currentChart.marginBottom;
79
+ }
80
+
81
+ // set the new size of the chart
82
+ if (totalHeight !== currentChart.chartHeight) {
83
+ currentChart.setSize(null, totalHeight, false);
84
+ }
85
+ };
86
+
21
87
  // Add zero line or custom reference line (but only for column or line charts)
22
88
  getReferenceLine = (customReferenceLineValue, chartType) => {
23
89
  let lineValue = 0;
@@ -38,6 +104,80 @@ class SpecificChartOptions {
38
104
  },
39
105
  };
40
106
  };
107
+
108
+ updateLegendSymbols = (chart) => {
109
+ if (chart.legend.options.enabled) {
110
+ chart.legend.allItems.forEach((item, index) => {
111
+ const { legendItem, userOptions } = item;
112
+ const seriesType = userOptions?.type;
113
+ const { label, symbol, line } = legendItem || {};
114
+
115
+ if (seriesType === 'line') {
116
+ // This is the case for the column plus line chart - the series type is
117
+ // line, but the chart type is column. In this case we show a simple
118
+ // line symbol in the legend, but we need to move the label to the right
119
+ // to account for the longer line symbol
120
+ if (chart.userOptions.chart.type !== 'line') {
121
+ label?.attr({
122
+ x: 30, // Adjust label position to account for longer line
123
+ });
124
+ }
125
+
126
+ // This is the scenario for a line chart with markers disabled
127
+ // We have custom code in line-chart.js to update the last point to
128
+ // display as a symbol. This code checks if there is no symbol in the legend
129
+ // (which means it is a line chart with markers disabled)
130
+ // and if so, it updates the legend to display as a symbol rather than as a line
131
+ // We only to this for chart types that are explicitly line charts - i.e. not column with line
132
+ if (!symbol && label && label.element && chart.userOptions.chart.type === 'line') {
133
+ // Hide the line in the legend
134
+ if (line) {
135
+ line.hide();
136
+ }
137
+
138
+ // Remove any existing custom symbols for this legend item
139
+ const existingSymbols = label.parentGroup.element.querySelectorAll('[data-custom-legend-symbol]');
140
+ existingSymbols.forEach((symbol) => symbol.remove());
141
+
142
+ // Create a custom symbol for the legend using the line marker symbol options
143
+ const renderer = chart.renderer;
144
+ const bbox = label.element.getBBox();
145
+ const markerStyle = this.constants.lineMarkerStyles[index % this.constants.lineMarkerStyles.length];
146
+
147
+ const legendSymbol = renderer
148
+ .symbol(markerStyle.symbol, bbox.x - 22, bbox.y + 4, 12, markerStyle.radius, markerStyle.radius)
149
+ .attr({
150
+ fill: item.color,
151
+ stroke: item.color,
152
+ 'stroke-width': 1,
153
+ width: 12,
154
+ height: 12,
155
+ 'data-custom-legend-symbol': true,
156
+ });
157
+ legendSymbol.add(label.parentGroup);
158
+ label?.attr({
159
+ x: 15, // Adjust label position to account for shorter space that the symbol takes up
160
+ });
161
+ }
162
+ } else if (seriesType === 'columnrange') {
163
+ symbol.attr({
164
+ width: 14,
165
+ height: 14,
166
+ y: 8,
167
+ });
168
+ } else {
169
+ if (!symbol) return;
170
+ // Update the symbol width and height
171
+ // For column, bar and other chart types
172
+ symbol.attr({
173
+ width: 12,
174
+ height: 12,
175
+ y: 8,
176
+ });
177
+ }
178
+ });
179
+ }
180
+ };
41
181
  }
42
182
 
43
183
  export default SpecificChartOptions;
@@ -41,17 +41,17 @@
41
41
  }
42
42
 
43
43
  &--inline {
44
- .ons-description-list__term {
45
- padding-right: 1rem;
46
- }
47
-
48
44
  @include mq(l) {
49
45
  display: grid;
50
46
  grid-template-columns: repeat(3, 1fr);
51
- grid-template-rows: repeat(2, 1fr);
52
- grid-auto-flow: column;
47
+ grid-auto-rows: auto;
48
+ grid-auto-flow: row;
53
49
  gap: 0.5rem 2.5rem;
54
50
 
51
+ &-single {
52
+ grid-template-columns: 1fr;
53
+ }
54
+
55
55
  .ons-description-list__value {
56
56
  grid-column-start: 2;
57
57
  }
@@ -59,6 +59,7 @@
59
59
  .ons-description-list__item {
60
60
  display: grid;
61
61
  grid-template-columns: auto 1fr;
62
+ grid-column-gap: 1rem;
62
63
  }
63
64
  }
64
65
  }
@@ -1,6 +1,6 @@
1
1
  {% macro onsDescriptionList(params) %}
2
2
  <dl
3
- class="ons-description-list ons-description-list__items ons-grid ons-grid--gutterless{{ ' ons-description-list--inline' if params.variant == 'inline' else ' ons-u-cf' }}{{ ' ' + params.classes if params.classes else '' }}"
3
+ class="ons-description-list ons-description-list__items ons-grid ons-grid--gutterless{{ ' ons-description-list--inline' if params.variant == 'inline' else ' ons-u-cf' }}{{ ' ons-description-list--inline-single' if params.itemsList|length < 2 else '' }}{{ ' ' + params.classes if params.classes else '' }}"
4
4
  {% if params.id %}id="{{ params.id }}"{% endif %}
5
5
  {% if params.descriptionListLabel %}
6
6
  title="{{ params.descriptionListLabel }}" aria-label="{{ params.descriptionListLabel }}"
@@ -20,6 +20,27 @@
20
20
  background-color: var(--ons-color-ocean-blue);
21
21
  color: var(--ons-color-white);
22
22
  border: 1px solid var(--ons-color-ocean-blue);
23
+
24
+ // remove browser default arrow for <details>
25
+ &::marker,
26
+ &::-webkit-details-marker {
27
+ display: none;
28
+ }
29
+
30
+ &:focus {
31
+ outline: 0;
32
+
33
+ #{$root}__banner-detail {
34
+ background: var(--ons-color-focus);
35
+ box-shadow: 0 ems($button-shadow-size) 0 var(--ons-color-text-link-focus);
36
+ color: var(--ons-color-text-link-focus);
37
+ outline: none;
38
+ }
39
+
40
+ #{$root}__banner-detail-title {
41
+ text-decoration: none;
42
+ }
43
+ }
23
44
  }
24
45
 
25
46
  &__banner-contents {
@@ -29,22 +50,28 @@
29
50
  &__banner-detail {
30
51
  width: fit-content;
31
52
  cursor: pointer;
32
-
33
- &:focus {
34
- background: var(--ons-color-focus);
35
- box-shadow: 0 ems($button-shadow-size) 0 var(--ons-color-text-link-focus);
36
- color: var(--ons-color-text-link-focus);
37
- outline: none;
38
- }
39
53
  }
40
54
 
41
55
  &__banner-detail-title {
42
56
  text-decoration: underline var(--ons-color-white) 2px;
43
57
  text-underline-position: under;
44
- }
58
+ display: inline-block;
59
+
60
+ &--open {
61
+ display: inline;
45
62
 
46
- &__banner-detail:focus &__banner-detail-title {
47
- text-decoration: none;
63
+ #{$root}[open] & {
64
+ display: none;
65
+ }
66
+ }
67
+
68
+ &--close {
69
+ display: none;
70
+
71
+ #{$root}[open] & {
72
+ display: inline;
73
+ }
74
+ }
48
75
  }
49
76
 
50
77
  &__banner-detail-icon {
@@ -65,19 +92,12 @@
65
92
  #{$root}[open] & {
66
93
  display: block;
67
94
  }
68
-
69
- .ons-details--initialised & {
70
- display: none;
71
- }
72
95
  }
73
96
 
74
97
  &__item {
75
98
  display: flex;
76
99
  flex-direction: column;
77
100
  border-bottom: 1px solid var(--ons-color-borders);
78
- @extend .ons-u-pb-xl;
79
- @extend .ons-u-mb-l;
80
- @extend .ons-u-ml-2xs;
81
101
 
82
102
  @include mq('m') {
83
103
  flex-direction: row;
@@ -85,14 +105,16 @@
85
105
  }
86
106
 
87
107
  &:last-child {
88
- border-bottom: 0;
89
108
  @extend .ons-u-mb-no;
90
109
  @extend .ons-u-pb-no;
110
+
111
+ border-bottom: 0;
91
112
  }
92
113
  }
93
114
 
94
115
  &__content-meta {
95
116
  @extend .ons-u-mb-no;
117
+
96
118
  @include mq('m') {
97
119
  flex-basis: 25%;
98
120
  min-width: 16.5rem;
@@ -101,7 +123,5 @@
101
123
 
102
124
  &__content-heading {
103
125
  color: var(--ons-color-black);
104
- @extend .ons-u-fs-r--b;
105
- @extend .ons-u-mb-no;
106
126
  }
107
127
  }
@@ -1,6 +1,9 @@
1
1
  {% macro onsDetailsPanel(params) %}
2
- <div class="ons-details-panel ons-js-details" {% if params.open %}{{ ' ' }}data-open="true"{% endif %}>
3
- <div class="ons-details-panel__banner ons-u-pt-s ons-u-pb-s">
2
+ {% set openText = params.openText | default("Show detail") %}
3
+ {% set closeText = params.closeText | default("Hide detail") %}
4
+
5
+ <details class="ons-details-panel" {% if params.open %}{{ ' ' }}data-open{% endif %}>
6
+ <summary class="ons-details-panel__banner ons-u-pt-s ons-u-pb-s">
4
7
  <div class="ons-container ons-details-panel__banner-contents">
5
8
  <span class="ons-details-panel__info-icon ons-u-mr-2xs" aria-hidden="true">i</span>
6
9
  <div class="ons-details-panel__banner-body">
@@ -9,10 +12,11 @@
9
12
  {% set closingTag = "</h" ~ titleTag ~ ">" %}
10
13
  {{ openingTag | safe }}
11
14
  class="ons-details-panel__banner-title ons-u-fs-m ons-u-mb-2xs">{{ params.title }}{{ closingTag | safe }}
12
- <div class="ons-details-panel__banner-detail ons-js-details-heading">
13
- <span class="ons-details-panel__banner-detail-title ons-js-corrections-details-title ons-u-mr-3xs"
14
- >Show detail</span
15
- >
15
+ <div class="ons-details-panel__banner-detail">
16
+ <span class="ons-details-panel__banner-detail-title ons-u-mr-3xs">
17
+ <span class="ons-details-panel__banner-detail-title--open"> {{ openText }} </span>
18
+ <span class="ons-details-panel__banner-detail-title--close"> {{ closeText }} </span>
19
+ </span>
16
20
  <span class="ons-details-panel__banner-detail-icon">
17
21
  {% from "components/icon/_macro.njk" import onsIcon %}
18
22
  {{
@@ -24,22 +28,24 @@
24
28
  </div>
25
29
  </div>
26
30
  </div>
27
- </div>
28
- <div class="ons-container ons-details-panel__content ons-js-details-content ons-u-pt-xl ons-u-pb-3xl">
31
+ </summary>
32
+ <div class="ons-container ons-details-panel__content ons-u-pt-xl ons-u-pb-3xl">
29
33
  {% for item in params.detailsItems %}
30
- <div class="ons-details-panel__item">
34
+ <div class="ons-details-panel__item ons-u-pb-xl ons-u-mb-l ons-u-ml-2xs">
31
35
  <div class="ons-details-panel__content-meta ons-u-mb-l@2xs@m">
32
- <h3 class="ons-details-panel__content-heading">{{ item.text }}</h3>
36
+ <h3 class="ons-details-panel__content-heading ons-u-fs-r--b ons-u-mb-no">{{ item.text }}</h3>
33
37
  <time class="ons-details-panel__content-date" datetime="{{ item.date.iso }}">{{ item.date.short }}</time>
34
38
  </div>
35
39
  <div class="ons-details-panel__content-description">
36
40
  <div class="ons-details-panel__content-text ons-u-mb-s">{{ item.description | safe }}</div>
37
41
  {% if item.url or item.text == 'Content' %}
38
- <a class="ons-details-panel__content-url" href="{{ item.url }}"> View superseded version</a>
42
+ <a class="ons-details-panel__content-url" href="{{ item.url }}">
43
+ {{ item.urlText | default("View superseded version") }}
44
+ </a>
39
45
  {% endif %}
40
46
  </div>
41
47
  </div>
42
48
  {% endfor %}
43
49
  </div>
44
- </div>
50
+ </details>
45
51
  {% endmacro %}
@@ -3,6 +3,7 @@
3
3
  {{
4
4
  onsDetailsPanel({
5
5
  "title": "Correction and Notice",
6
+ "headingLevel": 3,
6
7
  "detailsItems": [
7
8
  {
8
9
  "text": 'Correction',
@@ -0,0 +1,76 @@
1
+ {% from "components/chart/_macro.njk" import onsChart %}
2
+ {% from "components/image/_macro.njk" import onsImage %}
3
+
4
+ {% macro onsFeaturedArticle(params) %}
5
+ {% set headingLevel = params.headingLevel | default(2) %}
6
+ {% set openingArticleTitleTag = "<h" ~ headingLevel %}
7
+ {% set closingArticleTitleTag = "</h" ~ headingLevel ~ ">" %}
8
+
9
+ <div class="ons-featured">
10
+ {{ openingArticleTitleTag | safe }} class="ons-featured__title ons-u-fs-m ons-u-mt-no ons-u-mb-2xs">
11
+ <a href="{{ params.title.url }}">{{ params.title.text }}</a>
12
+ {{ closingArticleTitleTag | safe }}
13
+
14
+ {%- if params.metadata -%}
15
+ {% set metadata = params.metadata %}
16
+ <ul class="ons-featured__item-metadata">
17
+ {%- if metadata.date -%}
18
+ <li class="ons-featured__item-attribute">
19
+ {% set prefixClass = "ons-u-fw-b" if metadata.date.showPrefix == true else "ons-u-vh" %}
20
+ <span class="{{ prefixClass }}">{{ metadata.date.prefix | default("Published") }}: </span>
21
+ {%- if metadata.date.iso -%}
22
+ <time datetime="{{ metadata.date.iso }}">{{ metadata.date.short }}</time>
23
+ {%- endif -%}
24
+ </li>
25
+ {% endif %}
26
+
27
+ {%- if metadata.text -%}
28
+ <li class="ons-featured__item-attribute">
29
+ <span {% if metadata.text %}class="ons-featured__attribute-text ons-u-fw-b"{% endif %}>{{ metadata.text }}</span>
30
+ </li>
31
+ {% endif %}
32
+ </ul>
33
+ {% endif %}
34
+
35
+ <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 %}
70
+ </div>
71
+
72
+ {% if params.description %}
73
+ <div class="ons-featured__description">{{ params.description | safe }}</div>
74
+ {% endif %}
75
+ </div>
76
+ {% endmacro %}