@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.
- package/README.md +9 -5
- package/components/announcement-banner/_announcement-banner.scss +24 -0
- package/components/announcement-banner/_macro.njk +33 -0
- package/components/announcement-banner/_macro.spec.js +106 -0
- package/components/announcement-banner/_test_examples.js +22 -0
- package/components/announcement-banner/example-banner-black.njk +12 -0
- package/components/announcement-banner/example-banner-red.njk +13 -0
- package/components/announcement-banner/example-banner-teal.njk +13 -0
- package/components/button/_button.scss +29 -1
- package/components/chart/_chart.scss +3 -0
- package/components/chart/_macro.njk +10 -4
- package/components/chart/_macro.spec.js +1150 -642
- package/components/chart/chart-iframe-resize.js +2 -2
- package/components/chart/example-iframe-chart.njk +1 -1
- package/components/duration/example-duration-error-for-single-field.njk +0 -1
- package/components/duration/example-duration-error.njk +0 -1
- package/components/footer/_macro.spec.js +2 -2
- package/components/header/_macro.njk +5 -16
- package/components/header/example-header-button-and-navigation.njk +133 -0
- package/components/header/example-header-external-with-navigation-and-search.njk +1 -1
- package/components/navigation/_macro.njk +11 -16
- package/components/navigation/_navigation.scss +24 -0
- package/components/table/_macro.njk +107 -112
- package/components/table/_macro.spec.js +35 -44
- package/components/table/_table.scss +0 -12
- package/components/table/example-table-sortable.njk +1 -1
- package/components/tabs/example-tabs-details.njk +1 -1
- package/components/textarea/_macro.njk +1 -0
- package/components/textarea/_macro.spec.js +1 -0
- package/components/timeout-panel/timeout-panel.spec.js +1 -1
- package/css/main.css +1 -1
- package/layout/_template.njk +13 -0
- package/package.json +3 -3
- package/scripts/main.es5.js +1 -1
- package/scripts/main.js +1 -1
- package/scss/main.scss +1 -0
- package/scss/vars/_colors.scss +3 -0
- package/scss/vars/_forms.scss +11 -0
- 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
|
-
##
|
|
17
|
+
## Running the DS Locally
|
|
18
18
|
|
|
19
|
-
You'll need
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 }}
|