@ons/design-system 72.4.0 → 72.5.0

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 (46) hide show
  1. package/components/button/_button.scss +171 -3
  2. package/components/button/_macro.njk +4 -0
  3. package/components/card/_card.scss +5 -0
  4. package/components/card/_macro.njk +10 -2
  5. package/components/card/_macro.spec.js +58 -0
  6. package/components/card/example-card-set-with-headline-figures.njk +62 -0
  7. package/components/chart/_chart.scss +29 -0
  8. package/components/chart/_macro.njk +101 -0
  9. package/components/chart/_macro.spec.js +437 -0
  10. package/components/chart/bar-chart.js +160 -0
  11. package/components/chart/chart-constants.js +21 -0
  12. package/components/chart/chart.dom.js +8 -0
  13. package/components/chart/chart.js +157 -0
  14. package/components/chart/column-chart.js +48 -0
  15. package/components/chart/common-chart-options.js +200 -0
  16. package/components/chart/example-bar-chart.njk +54 -0
  17. package/components/chart/example-clustered-bar-chart.njk +60 -0
  18. package/components/chart/example-clustered-column-chart.njk +72 -0
  19. package/components/chart/example-column-chart.njk +52 -0
  20. package/components/chart/example-line-chart.njk +219 -0
  21. package/components/chart/example-stacked-bar-chart.njk +60 -0
  22. package/components/chart/example-stacked-column-chart.njk +65 -0
  23. package/components/chart/line-chart.js +47 -0
  24. package/components/chart/specific-chart-options.js +22 -0
  25. package/components/footer/_footer.scss +12 -0
  26. package/components/footer/_macro.njk +38 -17
  27. package/components/header/_header.scss +18 -2
  28. package/components/header/_macro.njk +81 -8
  29. package/components/header/_macro.spec.js +97 -0
  30. package/components/header/example-header-with-search-button.njk +190 -0
  31. package/components/header/header.spec.js +128 -0
  32. package/components/hero/_hero.scss +8 -7
  33. package/components/hero/_macro.njk +45 -26
  34. package/components/hero/example-hero-grey.njk +1 -0
  35. package/components/icon/_macro.njk +8 -8
  36. package/components/input/_input.scss +15 -0
  37. package/components/input/_macro.njk +3 -3
  38. package/components/navigation/navigation.dom.js +17 -0
  39. package/components/navigation/navigation.js +72 -2
  40. package/css/main.css +1 -1
  41. package/js/main.js +2 -0
  42. package/package.json +4 -1
  43. package/scripts/main.es5.js +1 -1
  44. package/scripts/main.js +1 -1
  45. package/scss/main.scss +1 -0
  46. package/scss/utilities/_grid.scss +13 -4
@@ -35,6 +35,52 @@ $button-shadow-size: 3px;
35
35
  }
36
36
  }
37
37
 
38
+ &--header-search &,
39
+ &--header-search:focus &,
40
+ &--header-search:active &,
41
+ &--header-search.active &,
42
+ &--header-search:active:focus &,
43
+ &--header-search.active:focus & {
44
+ &__inner {
45
+ background: var(--ons-color-ocean-blue) !important;
46
+ }
47
+ }
48
+
49
+ &--header-search &,
50
+ &--header-search:active &,
51
+ &--header-search.active & {
52
+ &__inner {
53
+ padding: 0.75rem !important;
54
+ border: 2px solid var(--ons-color-ocean-blue);
55
+ border-radius: 0;
56
+ box-shadow: none;
57
+ .ons-icon {
58
+ fill: var(--ons-color-text-inverse) !important;
59
+ height: 28px;
60
+ width: 28px;
61
+ }
62
+ }
63
+ }
64
+
65
+ &--header-search:hover & {
66
+ &__inner {
67
+ background: var(--ons-color-night-blue) !important;
68
+ border-color: var(--ons-color-text-link-hover);
69
+ }
70
+ }
71
+
72
+ &--header-search:focus & {
73
+ &__inner {
74
+ box-shadow:
75
+ 0 0 0 1px var(--ons-color-black),
76
+ 0 0 0 4px var(--ons-color-focus) !important;
77
+ outline: 3px solid rgb(0 0 0 / 0%);
78
+ outline-offset: 1px;
79
+ z-index: 4;
80
+ border: 2px solid var(--ons-color-black);
81
+ }
82
+ }
83
+
38
84
  &__inner {
39
85
  background: var(--ons-color-button);
40
86
  border-radius: $input-radius;
@@ -556,7 +602,7 @@ $button-shadow-size: 3px;
556
602
  &--menu {
557
603
  align-items: center;
558
604
  display: flex;
559
- padding: 1.5rem;
605
+ padding: 1rem;
560
606
  border-bottom: 4px solid rgb(0 0 0 / 0%);
561
607
  .ons-icon {
562
608
  transform: rotate(90deg);
@@ -575,12 +621,15 @@ $button-shadow-size: 3px;
575
621
  margin-top: 0;
576
622
  width: 1rem;
577
623
  }
624
+ .ons-btn__text {
625
+ height: 24px;
626
+ }
578
627
  }
579
628
  }
580
629
 
581
630
  &--menu:focus {
582
- background-color: var(--ons-color-focus);
583
- border-color: var(--ons-color-black);
631
+ background-color: var(--ons-color-focus) !important;
632
+ border-color: var(--ons-color-black) !important;
584
633
  }
585
634
 
586
635
  &--menu:hover {
@@ -589,6 +638,13 @@ $button-shadow-size: 3px;
589
638
 
590
639
  &--menu:focus & {
591
640
  &__inner {
641
+ .ons-icon {
642
+ fill: var(--ons-color-text-link-focus) !important;
643
+ }
644
+ .ons-btn__text {
645
+ color: var(--ons-color-text-link-focus);
646
+ }
647
+
592
648
  box-shadow: none;
593
649
  }
594
650
  }
@@ -629,6 +685,118 @@ $button-shadow-size: 3px;
629
685
  }
630
686
  }
631
687
  }
688
+
689
+ &--search-icon,
690
+ &--close {
691
+ border-bottom: 4px solid transparent;
692
+ align-items: center;
693
+ display: flex;
694
+ padding: 1rem;
695
+ }
696
+
697
+ &--search-icon &,
698
+ &--close & {
699
+ &__inner {
700
+ background: rgb(0 0 0 / 0%);
701
+ box-shadow: none;
702
+ padding: 0;
703
+ .ons-icon {
704
+ @extend .ons-u-m-no;
705
+
706
+ fill: var(--ons-color-text-link);
707
+ height: 1.5rem;
708
+ width: 1.5rem;
709
+ }
710
+ }
711
+ }
712
+
713
+ &--search-icon:hover {
714
+ border-bottom: 4px solid rgb(0 0 0 / 0%);
715
+ border-color: var(--ons-color-text-link-hover);
716
+ }
717
+
718
+ &--search-icon:focus:hover:not(:active, .active) {
719
+ .ons-btn__inner {
720
+ background: none;
721
+ box-shadow: none;
722
+ }
723
+ }
724
+
725
+ &--close:focus:hover:not(:active, .active) {
726
+ .ons-btn__inner {
727
+ background: none;
728
+ box-shadow: none;
729
+ }
730
+ }
731
+
732
+ &--close:active,
733
+ &--close[aria-expanded='true'] {
734
+ @extend .ons-u-ml-no;
735
+
736
+ border-color: var(--ons-color-text-link-hover);
737
+ background-color: var(--ons-color-branded-tint);
738
+ .ons-btn__inner {
739
+ .ons-icon {
740
+ fill: var(--ons-color-text-link-hover);
741
+ }
742
+ }
743
+ }
744
+
745
+ &--search-icon:hover &,
746
+ &--search-icon:active &,
747
+ &--search-icon:active:focus &,
748
+ &--search-icon.active &,
749
+ &--search-icon.active:focus & {
750
+ &__inner {
751
+ background: none;
752
+ box-shadow: none;
753
+ color: var(--ons-color-text-link-hover);
754
+ .ons-icon {
755
+ fill: var(--ons-color-text-link-hover);
756
+ }
757
+ }
758
+ }
759
+
760
+ &--search-icon:focus {
761
+ background-color: var(--ons-color-focus);
762
+ border-color: var(--ons-color-text-link-focus);
763
+ }
764
+
765
+ &--search-icon:focus &,
766
+ &--close:focus & {
767
+ &__inner {
768
+ background: none;
769
+ box-shadow: none;
770
+ .ons-icon {
771
+ fill: var(--ons-color-text-link-focus) !important;
772
+ }
773
+ }
774
+ }
775
+
776
+ &--close:focus {
777
+ background: var(--ons-color-focus);
778
+ border-color: var(--ons-color-black);
779
+ }
780
+
781
+ &--search-icon:active {
782
+ background-color: var(--ons-color-branded-tint);
783
+ border-color: var(--ons-color-text-link-hover);
784
+ }
785
+
786
+ &--close:hover &,
787
+ &--close:active &,
788
+ &--close.active &,
789
+ &--close.active:focus &,
790
+ &--close:active:focus & {
791
+ &__inner {
792
+ background: none !important;
793
+ box-shadow: none;
794
+ color: var(--ons-color-text-link-hover);
795
+ .ons-icon {
796
+ fill: var(--ons-color-text-link-hover);
797
+ }
798
+ }
799
+ }
632
800
  }
633
801
 
634
802
  .ons-search__btn {
@@ -61,6 +61,10 @@
61
61
  {% set iconType = "loader" %}
62
62
  {% set iconPosition = "after" %}
63
63
  {% set variantClasses = " ons-btn--loader ons-js-loader ons-js-submit-btn" %}
64
+ {% elif 'search' in params.variants %}
65
+ {% set iconType = "search" %}
66
+ {% elif 'close' in params.variants %}
67
+ {% set iconType = "close" %}
64
68
  {% endif %}
65
69
  {% endif %}
66
70
  {% set tag = "a" if params.url else "button" %}
@@ -2,6 +2,11 @@
2
2
  margin: 0 0 2rem;
3
3
  width: 100%;
4
4
 
5
+ &--feature {
6
+ background-color: var(--ons-color-banner-bg);
7
+ padding: 2rem;
8
+ }
9
+
5
10
  &__link {
6
11
  display: flex;
7
12
  flex-direction: column;
@@ -4,8 +4,8 @@
4
4
  {% set closingHeadingTag = "</h" + headingLevel + ">" %}
5
5
  {% set placeholderSrcset = (params.image.placeholderUrl if params.image.placeholderUrl else "") + "/img/small/placeholder-card.png 1x, " + (params.image.placeholderUrl if params.image.placeholderUrl else "") + "/img/large/placeholder-card.png 2x" %}
6
6
 
7
- <div class="ons-card">
8
- <a href="{{ params.title.url }}" class="ons-card__link">
7
+ <div class="ons-card {% if params.variant == "feature" %}ons-card--feature ons-u-flex-grow{% endif %}">
8
+ <a href="{{ params.title.url }}" class="ons-card__link {% if params.title.subtitle %}ons-u-mb-xs{% endif %}">
9
9
  {%- if params.image -%}
10
10
  {% if params.image.smallSrc %}
11
11
  <img
@@ -34,6 +34,14 @@
34
34
  {{ closingHeadingTag | safe }}
35
35
  </a>
36
36
 
37
+ {% if params.title.subtitle %}
38
+ <p class="ons-card__subtitle ons-u-fs-s">{{ params.title.subtitle }}</p>
39
+ {% endif %}
40
+
41
+ {% if params.body.figure %}
42
+ <p class="ons-card__figure ons-u-fs-3xl ons-u-fw-b ons-u-mb-no">{{ params.body.figure }}</p>
43
+ {% endif %}
44
+
37
45
  <p id="{{ params.body.id }}">{{ params.body.text }}</p>
38
46
 
39
47
  {%- if params.body.itemsList -%}
@@ -36,6 +36,20 @@ const EXAMPLE_CARD_WITH_PLACEHOLDER_IMAGE_WITH_PATH = {
36
36
  },
37
37
  };
38
38
 
39
+ const EXAMPLE_CARD_FEATURE_VARIANT = {
40
+ variant: 'feature',
41
+ title: {
42
+ text: 'Feature card title',
43
+ url: 'http://example.com',
44
+ subtitle: 'Optional subtitle',
45
+ },
46
+ body: {
47
+ figure: '123,456',
48
+ text: 'Example feature card text',
49
+ id: 'example-feature-text-id',
50
+ },
51
+ };
52
+
39
53
  describe('macro: card', () => {
40
54
  describe('mode: without image', () => {
41
55
  it('passes jest-axe checks', async () => {
@@ -267,4 +281,48 @@ describe('macro: card', () => {
267
281
  });
268
282
  });
269
283
  });
284
+
285
+ describe('variant: feature', () => {
286
+ it('renders the `feature` variant with correct class', () => {
287
+ const $ = cheerio.load(renderComponent('card', EXAMPLE_CARD_FEATURE_VARIANT));
288
+ expect($('.ons-card').hasClass('ons-card--feature')).toBe(true);
289
+ });
290
+
291
+ it('has the provided `title` text', () => {
292
+ const $ = cheerio.load(renderComponent('card', EXAMPLE_CARD_FEATURE_VARIANT));
293
+
294
+ expect($('.ons-card__title').text().trim()).toBe('Feature card title');
295
+ });
296
+
297
+ it('has the provided `subitle` text', () => {
298
+ const $ = cheerio.load(renderComponent('card', EXAMPLE_CARD_FEATURE_VARIANT));
299
+
300
+ expect($('.ons-card__subtitle').text().trim()).toBe('Optional subtitle');
301
+ });
302
+
303
+ it('outputs a hyperlink with the provided `url`', () => {
304
+ const $ = cheerio.load(renderComponent('card', EXAMPLE_CARD_FEATURE_VARIANT));
305
+
306
+ expect($('.ons-card__link').attr('href')).toBe('http://example.com');
307
+ });
308
+
309
+ it('has the provided `figure`', () => {
310
+ const $ = cheerio.load(renderComponent('card', EXAMPLE_CARD_FEATURE_VARIANT));
311
+
312
+ expect($('.ons-card__figure').text().trim()).toBe('123,456');
313
+ });
314
+
315
+ it('has the provided `text` accessible via the `textId` identifier', () => {
316
+ const $ = cheerio.load(renderComponent('card', EXAMPLE_CARD_FEATURE_VARIANT));
317
+
318
+ expect($('#example-feature-text-id').text().trim()).toBe('Example feature card text');
319
+ });
320
+
321
+ it('passes jest-axe checks', async () => {
322
+ const $ = cheerio.load(renderComponent('card', EXAMPLE_CARD_FEATURE_VARIANT));
323
+
324
+ const results = await axe($.html());
325
+ expect(results).toHaveNoViolations();
326
+ });
327
+ });
270
328
  });
@@ -0,0 +1,62 @@
1
+ {% from "components/card/_macro.njk" import onsCard %}
2
+
3
+ <div class="ons-container">
4
+ <div class="ons-grid ons-grid-flex ons-grid-flex--vertical-top">
5
+ <div class="ons-grid__col ons-grid__col--flex-col ons-grid__col--stretch ons-u-flex-grow ons-col-4@m">
6
+ {{
7
+ onsCard({
8
+ "variant": 'feature',
9
+ "title": {
10
+ "id": 'card-set-1',
11
+ "text": 'Deaths registered annually',
12
+ "url": '#0',
13
+ "subtitle": 'England and Wales'
14
+ },
15
+ "body":{
16
+ "id": 'text1',
17
+ "figure": '581,363',
18
+ "text": 'In 2023, up 0.7% from 2022'
19
+ }
20
+ })
21
+ }}
22
+ </div>
23
+
24
+ <div class="ons-grid__col ons-grid__col--flex-col ons-grid__col--stretch ons-u-flex-grow ons-col-4@m">
25
+ {{
26
+ onsCard({
27
+ "variant": 'feature',
28
+ "title": {
29
+ "id": 'card-set-2',
30
+ "text": 'Alcohol-specific deaths',
31
+ "url": '#0',
32
+ "subtitle": 'UK'
33
+ },
34
+ "body":{
35
+ "id": 'text2',
36
+ "figure": '10,473',
37
+ "text": 'In 2023, the highest number on record'
38
+ }
39
+ })
40
+ }}
41
+ </div>
42
+
43
+ <div class="ons-grid__col ons-grid__col--flex-col ons-grid__col--stretch ons-u-flex-grow ons-col-4@m">
44
+ {{
45
+ onsCard({
46
+ "variant": 'feature',
47
+ "title": {
48
+ "id": 'card-set-3',
49
+ "text": 'Suicides registered',
50
+ "subtitle": 'England and Wales',
51
+ "url": '#0'
52
+ },
53
+ "body":{
54
+ "id": 'text3',
55
+ "figure": '6069',
56
+ "text": 'In 2023, up 7.6% from 2022'
57
+ }
58
+ })
59
+ }}
60
+ </div>
61
+ </div>
62
+ </div>
@@ -0,0 +1,29 @@
1
+ .ons-chart {
2
+ margin: 0;
3
+
4
+ &__download-title {
5
+ @extend .ons-u-pt-l;
6
+ @extend .ons-u-fs-r--b;
7
+ }
8
+
9
+ &__title {
10
+ font-size: 1.25rem;
11
+ line-height: 1.625rem;
12
+ }
13
+
14
+ &__subtitle {
15
+ font-size: 1rem;
16
+ line-height: 1.3rem;
17
+ }
18
+
19
+ &__caption {
20
+ font-size: 1rem;
21
+ line-height: 1.2rem;
22
+ color: var(--ons-color-grey-75);
23
+ }
24
+ }
25
+
26
+ // This is a workaround to position the axis title to the left
27
+ .highcharts-axis-title {
28
+ width: 100%;
29
+ }
@@ -0,0 +1,101 @@
1
+ {% from "components/list/_macro.njk" import onsList %}
2
+
3
+ {% macro onsChart(params) %}
4
+ {% set supportedChartTypes = ['line', 'bar', 'column'] %}
5
+
6
+ {% if params.headingLevel and params.headingLevel >= 1 and params.headingLevel <= 4 %}
7
+ {% set headingLevel = params.headingLevel %}
8
+ {% else %}
9
+ {% set headingLevel = 2 %}
10
+ {% endif %}
11
+ {% set openingTitleTag = "<h" ~ headingLevel %}
12
+ {% set closingTitleTag = "</h" ~ headingLevel ~ ">" %}
13
+ {% set openingSubtitleTag = "<h" ~ (headingLevel + 1) %}
14
+ {% set closingSubtitleTag = "</h" ~ (headingLevel + 1) ~ ">" %}
15
+ {% set openingDownloadTitleTag = "<h" ~ (headingLevel + 2) %}
16
+ {% set closingDownloadTitleTag = "</h" ~ (headingLevel + 2) ~ ">" %}
17
+
18
+ <div
19
+ data-highcharts-base-chart
20
+ data-highcharts-type="{{ params.chartType }}"
21
+ data-highcharts-theme="{{ params.theme }}"
22
+ data-highcharts-title="{{ params.title }}"
23
+ data-highcharts-id="{{ params.id }}"
24
+ {% if params.useStackedLayout %}data-highcharts-use-stacked-layout="{{ params.useStackedLayout }}"{% endif %}
25
+ id="{{ params.id }}"
26
+ >
27
+ {% if params.chartType in supportedChartTypes %}
28
+ <figure class="ons-chart">
29
+ {{ openingTitleTag | safe }} class="ons-chart__title">{{ params.title }}{{ closingTitleTag | safe }}
30
+ {{ openingSubtitleTag | safe }}
31
+ class="ons-chart__subtitle">{{ params.subtitle }}{{ closingSubtitleTag | safe }}
32
+ {% if params.description %}
33
+ <p class="ons-u-vh">{{ params.description }}</p>
34
+ {% endif %}
35
+ <div data-highcharts-chart></div>
36
+ {% if params.caption %}
37
+ <figcaption class="ons-chart__caption">{{ params.caption }}</figcaption>
38
+ {% endif %}
39
+ </figure>
40
+ {% endif %}
41
+
42
+ {% if params.download.title and params.download.itemsList | length > 0 %}
43
+ {{ openingDownloadTitleTag | safe }}
44
+ class="ons-chart__download-title">{{ params.download.title }}{{ closingDownloadTitleTag | safe }}
45
+ {{
46
+ onsList({
47
+ "element": "ol",
48
+ "itemsList": params.download.itemsList
49
+ })
50
+ }}
51
+ {% endif %}
52
+ {% set series = [] %}
53
+ {% for item in params.series %}
54
+ {%
55
+ set series = series.concat({
56
+ "name": item.name if item.name else '',
57
+ "data": item.data if item.data else [],
58
+ "marker": {
59
+ "enabled": item.marker if item.marker else false
60
+ },
61
+ "dataLabels": {
62
+ "enabled": item.dataLabels if item.dataLabels else false
63
+ }
64
+ })
65
+ %}
66
+ {% endfor %}
67
+ {%
68
+ set config = {
69
+ "legend": {
70
+ "enabled" : params.legend
71
+ },
72
+ "yAxis": {
73
+ "title": {
74
+ "text": params.yAxis.title
75
+ },
76
+ "labels": {
77
+ "format": params.yAxis.labelFormat
78
+ }
79
+ },
80
+ "xAxis": {
81
+ "title": {
82
+ "text": params.xAxis.title
83
+ },
84
+ "categories": params.xAxis.categories,
85
+ "type": params.xAxis.type,
86
+ "labels": {
87
+ "format": params.xAxis.labelFormat
88
+ }
89
+ },
90
+ "series": series
91
+ }
92
+ %}
93
+
94
+ <!-- Set scripts to pass the config values as json to the javascript -->
95
+ <!-- prettier-ignore-start -->
96
+ <script type="application/json" data-highcharts-config--{{ params.id }}>
97
+ {{ config | dump | safe }}
98
+ </script>
99
+ <!-- prettier-ignore-end -->
100
+ </div>
101
+ {% endmacro %}