@ons/design-system 72.10.9 → 72.11.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 (39) hide show
  1. package/README.md +9 -5
  2. package/components/announcement-banner/_announcement-banner.scss +24 -0
  3. package/components/announcement-banner/_macro.njk +33 -0
  4. package/components/announcement-banner/_macro.spec.js +106 -0
  5. package/components/announcement-banner/_test_examples.js +22 -0
  6. package/components/announcement-banner/example-banner-black.njk +12 -0
  7. package/components/announcement-banner/example-banner-red.njk +13 -0
  8. package/components/announcement-banner/example-banner-teal.njk +13 -0
  9. package/components/button/_button.scss +29 -1
  10. package/components/chart/_chart.scss +3 -0
  11. package/components/chart/_macro.njk +10 -4
  12. package/components/chart/_macro.spec.js +1150 -642
  13. package/components/chart/chart-iframe-resize.js +2 -2
  14. package/components/chart/example-iframe-chart.njk +1 -1
  15. package/components/duration/example-duration-error-for-single-field.njk +0 -1
  16. package/components/duration/example-duration-error.njk +0 -1
  17. package/components/footer/_macro.spec.js +2 -2
  18. package/components/header/_macro.njk +5 -16
  19. package/components/header/example-header-button-and-navigation.njk +133 -0
  20. package/components/header/example-header-external-with-navigation-and-search.njk +1 -1
  21. package/components/navigation/_macro.njk +11 -16
  22. package/components/navigation/_navigation.scss +24 -0
  23. package/components/table/_macro.njk +107 -112
  24. package/components/table/_macro.spec.js +35 -44
  25. package/components/table/_table.scss +0 -12
  26. package/components/table/example-table-sortable.njk +1 -1
  27. package/components/tabs/example-tabs-details.njk +1 -1
  28. package/components/textarea/_macro.njk +1 -0
  29. package/components/textarea/_macro.spec.js +1 -0
  30. package/components/timeout-panel/timeout-panel.spec.js +1 -1
  31. package/css/main.css +1 -1
  32. package/layout/_template.njk +13 -0
  33. package/package.json +3 -3
  34. package/scripts/main.es5.js +1 -1
  35. package/scripts/main.js +1 -1
  36. package/scss/main.scss +1 -0
  37. package/scss/vars/_colors.scss +3 -0
  38. package/scss/vars/_forms.scss +11 -0
  39. package/components/table/example-table-scrollable.njk +0 -158
package/README.md CHANGED
@@ -14,26 +14,30 @@ Nunjucks macros for components and templates are available from npm. Built CSS a
14
14
  yarn add @ons/design-system
15
15
  ```
16
16
 
17
- ## Run Locally
17
+ ## Running the DS Locally
18
18
 
19
- You'll need [Git](https://help.github.com/articles/set-up-git/), [Node.js](https://nodejs.org/en/), and [Yarn](https://yarnpkg.com/en/docs/getting-started) to run this project locally.
19
+ You'll need to install:
20
+
21
+ - [Git](https://help.github.com/articles/set-up-git/)
22
+ - [Node.js](https://nodejs.org/en/)
23
+ - [Yarn](https://yarnpkg.com/en/docs/getting-started) (When installing yarn be sure to install yarn through brew using `brew install yarn` not using npm)
20
24
 
21
25
  The version of node required is outlined in [.nvmrc](./.nvmrc).
22
26
 
23
- ### Using nvm (optional)
27
+ ### Using NVM
24
28
 
25
29
  If you work across multiple Node.js projects there's a good chance they require different Node.js and npm versions.
26
30
 
27
31
  To enable this we use [nvm (Node Version Manager)](https://github.com/creationix/nvm) to switch between versions easily.
28
32
 
29
33
  1. [install nvm](https://github.com/creationix/nvm#installation)
30
- 2. Run nvm install in the project directory (this will use .nvmrc)
34
+ 2. Run `nvm install` in the project directory (this will use .nvmrc)
31
35
 
32
36
  ### Install dependencies
33
37
 
34
38
  ```bash
35
39
  yarn install
36
- yarn husky install
40
+ yarn husky
37
41
  ```
38
42
 
39
43
  ### Start a local server
@@ -0,0 +1,24 @@
1
+ .ons-announcement-banner {
2
+ color: var(--ons-color-text-inverse);
3
+ padding: 1rem;
4
+ &--black {
5
+ background-color: var(--ons-color-gov-black);
6
+ }
7
+
8
+ &--teal {
9
+ background-color: var(--ons-color-gov-teal);
10
+ }
11
+
12
+ &--red {
13
+ background-color: var(--ons-color-gov-red);
14
+ }
15
+
16
+ &__link {
17
+ color: var(--ons-color-text-inverse);
18
+
19
+ &:hover {
20
+ color: var(--ons-color-text-inverse);
21
+ text-decoration: underline solid var(--ons-color-text-inverse) 2px;
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,33 @@
1
+ {% macro onsAnnouncementBanner(params) %}
2
+
3
+ {% if params.variants %}
4
+ {% if 'wide' in params.variants %}
5
+ {% set width = "wide" %}
6
+ {% endif %}
7
+ {% endif %}
8
+
9
+ {% set content %}
10
+ <div
11
+ class="ons-announcement-banner{% if params.variants %}{% if params.variants == 'wide' or params.variants | length == 1 and 'wide' in params.variants %}{{ ' ' }}ons-announcement-banner--black{% elif params.variants is not string %}{% for variant in params.variants %}{{ ' ' }}ons-announcement-banner--{{ variant }}{% endfor %}{% else %}{{ ' ' }}ons-announcement-banner--{{ params.variants }}{% endif %}{% else %}{{ ' ' }}ons-announcement-banner--black{% endif %}"
12
+ >
13
+ <h2 class="ons-announcement-banner__title">{{ params.title }}</h2>
14
+ <p class="ons-announcement-banner__description">{{ params.description }}</p>
15
+ <a
16
+ class="ons-announcement-banner__link"
17
+ {% if params.link.attributes %}{% for attribute, value in (params.link.attributes.items() if params.link.attributes is mapping and params.link.attributes.items else params.link.attributes) %}{{ ' ' }}{{ attribute }}="{{ value }}"{% endfor %}{% endif %}
18
+ href="{{ params.link.url }}"
19
+ >{{ params.link.text }}</a
20
+ >
21
+ </div>
22
+ {% endset %}
23
+
24
+ {% if width != "wide" %}
25
+ <div
26
+ class="ons-announcement-banner__container{% if params.variants %}{% if params.variants is not string %}{% for variant in params.variants %}{{ ' ' }}ons-announcement-banner--{{ variant }}{% endfor %}{% else %}{{ ' ' }}ons-announcement-banner--{{ params.variants }}{% endif %}{% else %}{{ ' ' }}ons-announcement-banner--black{% endif %}"
27
+ >
28
+ <div class="ons-container">{{ content | safe }}</div>
29
+ </div>
30
+ {% else %}
31
+ {{ content | safe }}
32
+ {% endif %}
33
+ {% endmacro %}
@@ -0,0 +1,106 @@
1
+ /** @jest-environment jsdom */
2
+
3
+ import * as cheerio from 'cheerio';
4
+
5
+ import axe from '../../tests/helpers/axe';
6
+ import { renderComponent } from '../../tests/helpers/rendering';
7
+ import { EXAMPLE_FULL_ANNOUNCEMENT_BANNER, EXAMPLE_REQUIRED_ANNOUNCEMENT_BANNER } from './_test_examples';
8
+
9
+ describe('FOR: Macro: Announcement-banner', () => {
10
+ describe('GIVEN: Params: required', () => {
11
+ describe('WHEN: all required params are provided', () => {
12
+ const $ = cheerio.load(renderComponent('announcement-banner', EXAMPLE_REQUIRED_ANNOUNCEMENT_BANNER));
13
+ test('THEN: jest-axe checks pass', async () => {
14
+ const results = await axe($.html());
15
+ expect(results).toHaveNoViolations();
16
+ });
17
+
18
+ test('THEN: the title has the provided text', async () => {
19
+ const title = $('.ons-announcement-banner__title');
20
+ expect(title.text().trim()).toBe('This is a black banner');
21
+ });
22
+
23
+ test('THEN: the description has the provided text', async () => {
24
+ const description = $('.ons-announcement-banner__description');
25
+ expect(description.text().trim()).toBe('This is a description for the black banner');
26
+ });
27
+
28
+ test('THEN: the link points to the provided URL', async () => {
29
+ const linkUrl = $('.ons-announcement-banner__link');
30
+ expect(linkUrl.attr('href')).toBe('http://example.com');
31
+ });
32
+
33
+ test('THEN: the link has the provided link text', async () => {
34
+ const linkText = $('.ons-announcement-banner__link');
35
+ expect(linkText.text().trim()).toBe('Find out more');
36
+ });
37
+
38
+ test('THEN: it defaults to the black variant', async () => {
39
+ const banner = $('.ons-announcement-banner');
40
+ expect(banner.hasClass('ons-announcement-banner--black')).toBe(true);
41
+ });
42
+
43
+ test('THEN: containers are created', () => {
44
+ expect($('.ons-announcement-banner--black > .ons-container').length).toBe(1);
45
+ });
46
+ });
47
+ });
48
+
49
+ describe('GIVEN: Params: link attributes', () => {
50
+ const $ = cheerio.load(renderComponent('announcement-banner', EXAMPLE_FULL_ANNOUNCEMENT_BANNER));
51
+ describe('WHEN: link attributes are provided', () => {
52
+ test('THEN: the link has the provided attributes', async () => {
53
+ const link = $('.ons-announcement-banner__link');
54
+ expect(link.attr('abc')).toBe('123');
55
+ expect(link.attr('def')).toBe('456');
56
+ });
57
+ });
58
+ });
59
+
60
+ describe('GIVEN: Params: variants', () => {
61
+ describe('WHEN: variants is provided as a string', () => {
62
+ const $ = cheerio.load(renderComponent('announcement-banner', EXAMPLE_FULL_ANNOUNCEMENT_BANNER));
63
+ test('THEN: the banner has the correct variant class', async () => {
64
+ const banner = $('.ons-announcement-banner');
65
+ expect(banner.hasClass('ons-announcement-banner--red')).toBe(true);
66
+ });
67
+ });
68
+ describe('WHEN: wide is provided as one of the variants', () => {
69
+ const $ = cheerio.load(
70
+ renderComponent('announcement-banner', { ...EXAMPLE_REQUIRED_ANNOUNCEMENT_BANNER, variants: ['wide', 'red'] }),
71
+ );
72
+ test('THEN: containers are not created with the correct classes', () => {
73
+ expect($('.ons-announcement-banner--red > .ons-container').length).toBe(0);
74
+ });
75
+ });
76
+ describe('WHEN: red is provided alongside other variants', () => {
77
+ const $ = cheerio.load(
78
+ renderComponent('announcement-banner', { ...EXAMPLE_REQUIRED_ANNOUNCEMENT_BANNER, variants: ['wide', 'red'] }),
79
+ );
80
+ test('THEN: the banner has the correct variant class', async () => {
81
+ const banner = $('.ons-announcement-banner');
82
+ expect(banner.hasClass('ons-announcement-banner--red')).toBe(true);
83
+ });
84
+ });
85
+ describe('WHEN: wide is provided as the only variant as a string', () => {
86
+ const $ = cheerio.load(renderComponent('announcement-banner', { ...EXAMPLE_REQUIRED_ANNOUNCEMENT_BANNER, variants: 'wide' }));
87
+ test('THEN: it defaults to the black variant', async () => {
88
+ const banner = $('.ons-announcement-banner');
89
+ expect(banner.hasClass('ons-announcement-banner--black')).toBe(true);
90
+ });
91
+ test('THEN: containers are not created with the correct classes', () => {
92
+ expect($('.ons-announcement-banner--black > .ons-container').length).toBe(0);
93
+ });
94
+ });
95
+ describe('WHEN: wide is provided as the only variant in an array', () => {
96
+ const $ = cheerio.load(renderComponent('announcement-banner', { ...EXAMPLE_REQUIRED_ANNOUNCEMENT_BANNER, variants: ['wide'] }));
97
+ test('THEN: it defaults to the black variant', async () => {
98
+ const banner = $('.ons-announcement-banner');
99
+ expect(banner.hasClass('ons-announcement-banner--black')).toBe(true);
100
+ });
101
+ test('THEN: containers are not created with the correct classes', () => {
102
+ expect($('.ons-announcement-banner--black > .ons-container').length).toBe(0);
103
+ });
104
+ });
105
+ });
106
+ });
@@ -0,0 +1,22 @@
1
+ export const EXAMPLE_FULL_ANNOUNCEMENT_BANNER = {
2
+ variants: 'red',
3
+ title: 'This is a red banner',
4
+ description: 'This is a description for the red banner',
5
+ link: {
6
+ text: 'Find out more',
7
+ url: 'http://example.com',
8
+ attributes: {
9
+ abc: '123',
10
+ def: '456',
11
+ },
12
+ },
13
+ };
14
+
15
+ export const EXAMPLE_REQUIRED_ANNOUNCEMENT_BANNER = {
16
+ title: 'This is a black banner',
17
+ description: 'This is a description for the black banner',
18
+ link: {
19
+ text: 'Find out more',
20
+ url: 'http://example.com',
21
+ },
22
+ };
@@ -0,0 +1,12 @@
1
+ {% from "components/announcement-banner/_macro.njk" import onsAnnouncementBanner %}
2
+
3
+ {{
4
+ onsAnnouncementBanner({
5
+ "title": 'His Royal Highness Henry VIII',
6
+ "description": '1491 to 1547',
7
+ "link": {
8
+ "text": 'Find out more',
9
+ "url": '#0'
10
+ }
11
+ })
12
+ }}
@@ -0,0 +1,13 @@
1
+ {% from "components/announcement-banner/_macro.njk" import onsAnnouncementBanner %}
2
+
3
+ {{
4
+ onsAnnouncementBanner({
5
+ "variants": ['red', 'wide'],
6
+ "title": 'National emergency',
7
+ "description": 'This is a level 1 incident',
8
+ "link": {
9
+ "text": 'More information',
10
+ "url": '#0'
11
+ }
12
+ })
13
+ }}
@@ -0,0 +1,13 @@
1
+ {% from "components/announcement-banner/_macro.njk" import onsAnnouncementBanner %}
2
+
3
+ {{
4
+ onsAnnouncementBanner({
5
+ "variants": 'teal',
6
+ "title": 'Local emergency',
7
+ "description": 'This is a level 2 incident',
8
+ "link": {
9
+ "text": 'More information',
10
+ "url": '#0'
11
+ }
12
+ })
13
+ }}
@@ -99,7 +99,7 @@ $button-shadow-size: 3px;
99
99
  }
100
100
  }
101
101
 
102
- // When preceded by another button (for example, in a group)
102
+ // When preceded by another button (for example in a group)
103
103
  & + & {
104
104
  margin-left: 0.5rem;
105
105
  }
@@ -576,6 +576,34 @@ $button-shadow-size: 3px;
576
576
  }
577
577
  }
578
578
 
579
+ .ons-navigation--neutral &--dropdown {
580
+ .ons-btn__inner {
581
+ background: var(--ons-color-grey-15);
582
+ color: var(--ons-color-black);
583
+ .ons-icon {
584
+ fill: var(--ons-color-black);
585
+ }
586
+ }
587
+ &:focus {
588
+ .ons-btn__inner {
589
+ background: var(--ons-color-focus);
590
+ }
591
+ }
592
+ }
593
+
594
+ .ons-navigation--neutral &--dropdown:active &,
595
+ .ons-navigation--neutral &--dropdown.active &,
596
+ .ons-navigation--neutral &--dropdown:active:focus &,
597
+ .ons-navigation--neutral &--dropdown.active:focus & {
598
+ &__inner {
599
+ background: var(--ons-color-grey-100);
600
+ color: var(--ons-color-white);
601
+ .ons-icon {
602
+ fill: var(--ons-color-white);
603
+ }
604
+ }
605
+ }
606
+
579
607
  &--neutral &,
580
608
  &--neutral:hover &,
581
609
  &--neutral:active &,
@@ -126,6 +126,7 @@
126
126
 
127
127
  &__iframe {
128
128
  width: 100%;
129
+ aspect-ratio: 16 / 9; // Default aspect ratio
129
130
 
130
131
  @media (scripting: none) {
131
132
  // Approximately matches the aspect ratio of the fallback image inside the iframe
@@ -140,6 +141,8 @@
140
141
  }
141
142
  }
142
143
 
144
+ @include iframe-aspect-ratio('ons-chart__iframe--{x}');
145
+
143
146
  // This is a workaround to position the axis title to the left
144
147
  .highcharts-axis-title {
145
148
  width: 100%;
@@ -7,6 +7,7 @@
7
7
  {% set supportedChartTypesWithScatter = ['columnrange'] %}
8
8
  {% set supportedChartTypesWithXAxisMinAndMax = ['scatter'] %}
9
9
  {% set supportedChartTypesWithYAxisMinAndMax = ['line', 'bar', 'column', 'scatter', 'area', 'columnrange', 'boxplot'] %}
10
+ {% set supportedAspectRatios = ['16-9', '4-3', '21-9', '1-1', '3-2', '9-16'] %}
10
11
  {% set headingLevel = params.headingLevel | default(2) %}
11
12
  {% set openingTitleTag = "<h" ~ headingLevel %}
12
13
  {% set closingTitleTag = "</h" ~ headingLevel ~ ">" %}
@@ -16,6 +17,7 @@
16
17
  {% set closingDownloadTitleTag = "</h" ~ (headingLevel + 2) ~ ">" %}
17
18
  {% set audioDescriptionId = "chart-audio-description-" ~ params.id %}
18
19
  {% set instructionsId = "chart-instructions-" ~ params.id %}
20
+ {% set iframeAspectRatio = params.iframeAspectRatio if params.iframeAspectRatio in supportedAspectRatios else '16-9' %}
19
21
  {% set instructions = params.instructions | default('Use the Tab key to move focus into the chart. Once inside, use the arrow keys to navigate between data points. As you move, tooltips will be announced to describe each point. Touch device users, explore by touch or with swipe gestures.') %}
20
22
 
21
23
  <div
@@ -65,10 +67,14 @@
65
67
  <div
66
68
  class="ons-chart__iframe-wrapper{{ ' ons-chart__non-js-hide' if params.fallbackImageUrl else '' }}"
67
69
  id="{{ params.id }}"
68
- data-url="{{ params.iframeUrl }}"
69
- data-title="{{ params.title }}"
70
70
  >
71
- <iframe src="{{ params.iframeUrl }}" title="{{ params.title }}" class="ons-chart__iframe"></iframe>
71
+ <iframe
72
+ src="{{ params.iframeUrl }}"
73
+ title="{{ params.title }}"
74
+ class="ons-chart__iframe ons-chart__iframe--{{ iframeAspectRatio }}"
75
+ frameborder="0"
76
+ scrolling="no"
77
+ ></iframe>
72
78
  </div>
73
79
  {% else %}
74
80
  {% if params.chartType == 'boxplot' and (params.estimateLineLabel or params.uncertaintyRangeLabel) and params.legend == true %}
@@ -250,7 +256,7 @@
250
256
  }
251
257
  %}
252
258
 
253
- <!-- Set scripts to pass the config values as json to the javascript -->
259
+ <!-- Set scripts to pass the config values as json to the JavaScript -->
254
260
  <!-- prettier-ignore-start -->
255
261
  <script type="application/json" data-highcharts-config--{{ params.id }}>
256
262
  {{ config | tojson }}