mp-design-system 1.2.10 → 1.2.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. package/dist/build/js/app.js +1 -1
  2. package/dist/build/js/app.js.map +1 -1
  3. package/dist/build/scss/library.css +1 -1
  4. package/dist/build/scss/library.css.map +1 -1
  5. package/dist/build/scss/main.css +1 -1
  6. package/dist/build/scss/main.css.map +1 -1
  7. package/package.json +1 -1
  8. package/src/_headers +1 -1
  9. package/src/_includes/components/card/card.scss +0 -38
  10. package/src/_includes/components/card/event-series-card.config.js +36 -0
  11. package/src/_includes/components/card/event-series-card.njk +45 -0
  12. package/src/_includes/components/card/event-series-card.scss +57 -0
  13. package/src/_includes/components/comparison-table/comparison-table.scss +0 -1
  14. package/src/_includes/components/dynamic-form/dynamic-form.config.js +16 -0
  15. package/src/_includes/components/dynamic-form/dynamic-form.njk +319 -0
  16. package/src/_includes/components/dynamic-form/dynamic-form.scss +77 -0
  17. package/src/_includes/components/dynamic-form/macro.njk +5 -0
  18. package/src/_includes/components/embed/embed.scss +3 -0
  19. package/src/_includes/components/hero/hero.scss +1 -0
  20. package/src/_includes/components/input/combobox.njk +17 -0
  21. package/src/_includes/components/input/combobox.scss +31 -0
  22. package/src/_includes/components/input/combox.config.js +49 -0
  23. package/src/_includes/components/internal-nav/internal-nav.config.js +18 -0
  24. package/src/_includes/components/internal-nav/internal-nav.njk +14 -1
  25. package/src/_includes/components/internal-nav/internal-nav.scss +51 -21
  26. package/src/assets/js/app.js +2 -0
  27. package/src/assets/js/imports/combobox.js +66 -0
  28. package/src/assets/js/imports/internal-nav.js +23 -0
  29. package/src/assets/scss/components/index.scss +1 -0
  30. package/src/brand/illustration.md +8 -8
@@ -4,6 +4,7 @@
4
4
  color: color('petrol');
5
5
  position: relative;
6
6
  overflow: hidden;
7
+ isolation: isolate;
7
8
 
8
9
  &.mp .u-link {
9
10
  color: color('utility-blue');
@@ -0,0 +1,17 @@
1
+ {# <div class="c-combobox">
2
+ <input type="text" class="c-combobox__input" id="combobox-input" aria-haspopup="listbox" aria-expanded="false" aria-labelledby="combobox-label" autocomplete="off" placeholder="Select an option" role="combobox" aria-owns="combobox-options">
3
+ <ul class="c-combobox__dropdown" id="combobox-options" role="listbox" aria-labelledby="combobox-input">
4
+ <li data-value="option1" role="option">Option 1</li>
5
+ <li data-value="option2" role="option">Option 2</li>
6
+ <li data-value="option3" role="option">Option 3</li>
7
+ </ul>
8
+ <div> #}
9
+
10
+ <div class="c-combobox">
11
+ <input type="text" id="combobox-input" class="c-combobox__input" placeholder="Type to search..." autocomplete="off" aria-controls="combobox-list" role="combobox" aria-haspopup="listbox" aria-expanded="false" aria-owns="combobox-select">
12
+ <ul id="combobox-select" class="c-combobox__select" role="listbox" aria-label="Options" tabindex="-1">
13
+ <li role="option" aria-selected="false">Option 1</li>
14
+ <li role="option" aria-selected="false">Option 2</li>
15
+ <li role="option" aria-selected="false">Option 3</li>
16
+ </ul>
17
+ </div>
@@ -0,0 +1,31 @@
1
+ .c-combobox {
2
+ position: relative;
3
+ display: inline-block;
4
+
5
+ &__input {
6
+ width: 200px;
7
+ padding: 5px;
8
+ }
9
+
10
+ &__select {
11
+ position: absolute;
12
+ z-index: 1;
13
+ list-style-type: none;
14
+ padding: 0;
15
+ margin: 0;
16
+ background-color: #f9f9f9;
17
+ border: 1px solid #ccc;
18
+ border-top: none;
19
+ display: none;
20
+
21
+ li {
22
+ padding: 10px;
23
+ cursor: pointer;
24
+
25
+ &[aria-selected="true"] {
26
+ background-color: #e6e6e6;
27
+ }
28
+ }
29
+ }
30
+
31
+ }
@@ -0,0 +1,49 @@
1
+ const categories = require('../component/categories');
2
+
3
+ module.exports = {
4
+ title: 'Combobox',
5
+ category: categories.form,
6
+ component: {
7
+ name: 'combobox',
8
+ folder: 'input'
9
+ },
10
+ figma: 'https://www.figma.com/file/rUQ6aPQAfBX55o3hH0Lqb3/Design-exploration?node-id=213%3A918',
11
+ preview: 'form',
12
+ context: {
13
+ label: 'Label',
14
+ name: 'name',
15
+ id: 'id',
16
+ type: 'text',
17
+ placeholder: 'Placeholder',
18
+ required: true
19
+ },
20
+ variants: [
21
+ {
22
+ title: 'With error',
23
+ context: {
24
+ error: true
25
+ }
26
+ },
27
+ {
28
+ title: 'With error message',
29
+ context: {
30
+ error: 'This field is required'
31
+ }
32
+ },
33
+ {
34
+ title: 'Disabled',
35
+ context: {
36
+ disabled: true
37
+ }
38
+ }
39
+ ],
40
+ props: [
41
+ {
42
+ table: [
43
+ ['label', 'string'],
44
+ ['id', 'string', 'ID attribute'],
45
+ ['name', 'string', 'Name attribute (falls back to ID)'],
46
+ ]
47
+ }
48
+ ]
49
+ }
@@ -13,6 +13,24 @@ module.exports = {
13
13
  { link: '#our-product-brands', label: 'Our product brands' }
14
14
  ]
15
15
  },
16
+ variants: [
17
+ {
18
+ title: 'Sticky on scroll',
19
+ context: {
20
+ classes: 'u-sticky',
21
+ title: 'Mastersizer range',
22
+ links: [
23
+ { link: '#overview', label: 'Overview' },
24
+ { link: '#products', label: 'Products' },
25
+ { link: '#compare', label: 'Compare' },
26
+ ],
27
+ button: {
28
+ link: '#',
29
+ label: 'Request a quote',
30
+ }
31
+ }
32
+ }
33
+ ],
16
34
  props: [
17
35
  {
18
36
  table: [
@@ -1,9 +1,22 @@
1
+ {%- from "components/button/macro.njk" import button -%}
2
+
1
3
  <nav class="mp c-internal-nav {{ params.classes }}" aria-label="In-page">
2
4
  <div class="c-internal-nav__wrap">
5
+ {% if params.title %}
6
+ <p class="c-internal-nav__title">{{ params.title }}</p>
7
+ {% endif %}
3
8
  <ul class="c-internal-nav__list">
4
9
  {% for item in params.links %}
5
10
  <li><a href="{{ item.link }}">{{ item.label }}</a></li>
6
11
  {% endfor %}
12
+ {% if params.button %}
13
+ {{ button({
14
+ link: params.button.link,
15
+ label: params.button.label,
16
+ colour: 'green',
17
+ classes: 'c-button--small'
18
+ }) }}
19
+ {% endif %}
7
20
  </ul>
8
21
  </div>
9
- </nav>
22
+ </nav>
@@ -1,35 +1,65 @@
1
1
  .c-internal-nav {
2
- color: color('utility-blue');
2
+ background-color: transparent;
3
+ border-bottom: 1px solid color('grey', 'step-2');
4
+ transition: 300ms background-color;
3
5
 
4
- &__wrap {
5
- position: relative;
6
-
7
- &:after {
8
- content: '';
9
- background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
10
- position: absolute;
11
- z-index: 1;
12
- height: 100%;
13
- right: 0;
14
- top: 0;
15
- @include space('width', 'l');
16
-
17
- @media (min-width: $wrapper) {
18
- display: none;
19
- }
6
+ &--stuck {
7
+ @extend .u-bg-white;
8
+
9
+ .c-internal-nav__title {
10
+ opacity: 1;
20
11
  }
21
12
  }
22
13
 
14
+ &__wrap {
15
+ @extend .u-wrap;
16
+ display: flex;
17
+ gap: var(--space-l);
18
+ justify-content: space-between;
19
+ align-items: center;
20
+ }
21
+
22
+ &__title {
23
+ @include padding('s', 0);
24
+ flex-shrink: 0;
25
+ font-weight: bold;
26
+ transition: 300ms opacity;
27
+ opacity: 0;
28
+ }
29
+
23
30
  &__list {
24
- @include padding-bottom('m-l');
25
- @include margin-bottom('m-l');
26
- border-bottom: 1px solid color('petrol', 'step-2');
31
+ @include padding('s', 0);
32
+ color: color('utility-blue');
27
33
  white-space: nowrap;
28
34
  overflow-x: auto;
29
35
  display: flex;
36
+ align-items: center;
37
+ font-size: var(--step--1);
30
38
 
31
39
  & > * + * {
32
- @include margin-left('m-l');
40
+ @include margin-left('l');
41
+ }
42
+ }
43
+
44
+
45
+
46
+ @media (max-width: 44em) {
47
+ &__title,
48
+ .c-button {
49
+ display: none;
50
+ }
51
+
52
+ &__list {
53
+ @include padding-bottom('s');
33
54
  }
34
55
  }
35
56
  }
57
+
58
+
59
+ .c-hero + .c-internal-nav {
60
+ margin-top: calc(var(--gutter) * -1);
61
+ }
62
+
63
+ .c-internal-nav.u-sticky {
64
+ top: -1px;
65
+ }
@@ -5,6 +5,7 @@ import Comparison from './imports/comparison';
5
5
  import Gallery from './imports/gallery';
6
6
  import HeroPattern from './imports/hero-pattern';
7
7
  import HeroVideo from './imports/hero-video';
8
+ import InternalNav from './imports/internal-nav';
8
9
  import OffCanvas from './imports/off-canvas';
9
10
  import ResponsiveTable from './imports/responsive-table';
10
11
  import ScrollbarWidth from './imports/scrollbar-width';
@@ -26,6 +27,7 @@ import Tabs from './imports/tabs';
26
27
  Gallery();
27
28
  HeroPattern();
28
29
  HeroVideo();
30
+ InternalNav();
29
31
  OffCanvas();
30
32
  ResponsiveTable();
31
33
  ScrollbarWidth();
@@ -0,0 +1,66 @@
1
+ function Combobox() {
2
+ const comboboxes = Array.from(document.querySelectorAll('.c-combobox'));
3
+
4
+ comboboxes.forEach(function (combobox) {
5
+ const input = combobox.querySelector('.c-combobox__input');
6
+ const select = combobox.querySelector('.c-combobox__select');
7
+ const options = Array.from(select.querySelectorAll('li[role="option"]'));
8
+
9
+ // Set initial state
10
+ input.setAttribute('aria-expanded', 'false');
11
+ input.setAttribute('aria-owns', select.id);
12
+ input.setAttribute('aria-controls', select.id);
13
+
14
+ // Event listeners
15
+ input.addEventListener('focus', function () {
16
+ input.setAttribute('aria-expanded', 'true');
17
+ select.setAttribute('aria-expanded', 'true');
18
+ });
19
+
20
+ input.addEventListener('blur', function () {
21
+ input.setAttribute('aria-expanded', 'false');
22
+ select.setAttribute('aria-expanded', 'false');
23
+ });
24
+
25
+ input.addEventListener('input', function () {
26
+ const inputValue = input.value.toLowerCase();
27
+
28
+ options.forEach(function (option) {
29
+ const optionText = option.textContent.toLowerCase();
30
+
31
+ if (optionText.includes(inputValue)) {
32
+ option.style.display = '';
33
+ option.setAttribute('aria-hidden', 'false');
34
+ } else {
35
+ option.style.display = 'none';
36
+ option.setAttribute('aria-hidden', 'true');
37
+ }
38
+ });
39
+ });
40
+
41
+ select.addEventListener('click', function (event) {
42
+ const target = event.target;
43
+ const isOption = target.getAttribute('role') === 'option';
44
+
45
+ if (isOption) {
46
+ const selectedOption = select.querySelector('[aria-selected="true"]');
47
+ if (selectedOption) {
48
+ selectedOption.setAttribute('aria-selected', 'false');
49
+ }
50
+
51
+ target.setAttribute('aria-selected', 'true');
52
+ input.value = target.textContent;
53
+
54
+ input.focus();
55
+ }
56
+ });
57
+
58
+ // Display options initially
59
+ options.forEach(function (option) {
60
+ option.style.display = '';
61
+ option.setAttribute('aria-hidden', 'false');
62
+ });
63
+ });
64
+ }
65
+
66
+ export default Combobox;
@@ -0,0 +1,23 @@
1
+ function InternalNav() {
2
+ const internalNav = document.querySelector('.c-internal-nav.u-sticky');
3
+
4
+ if (!internalNav) {
5
+ return;
6
+ }
7
+
8
+ const observerOptions = {
9
+ root: null,
10
+ rootMargin: '0px',
11
+ threshold: 1.0
12
+ };
13
+
14
+ const intersectionCallback = (entries, observer) => {
15
+ const isIntersecting = entries[0].isIntersecting;
16
+ internalNav.classList.toggle('c-internal-nav--stuck', !isIntersecting);
17
+ };
18
+
19
+ const observer = new IntersectionObserver(intersectionCallback, observerOptions);
20
+ observer.observe(internalNav);
21
+ }
22
+
23
+ export default InternalNav;
@@ -4,6 +4,7 @@
4
4
  @import '~comp/button/button.scss';
5
5
  @import '~comp/campaign/campaign.scss';
6
6
  @import '~comp/card/card.scss';
7
+ @import '~comp/card/event-series-card.scss';
7
8
  @import '~comp/card/industry-card.scss';
8
9
  @import '~comp/card/product-comparison-card.scss';
9
10
  @import '~comp/comparison-table/comparison-table.scss';
@@ -25,23 +25,23 @@ We have a library of pre-made characters which can be adapted for new designs, a
25
25
 
26
26
  <div class="c-library__illustration-grid">
27
27
 
28
- ![alt text][login]
28
+ ![An illustration of several small people sitting and standing around an oversized laptop][login]
29
29
 
30
- ![alt text][thankyou]
30
+ ![An illustration of several small people carrying an oversized envelope][thankyou]
31
31
 
32
- ![alt text][confirm]
32
+ ![An illustration of one person welcoming another through a doorway, with golden light on the other side][confirm]
33
33
 
34
- ![alt text][support]
34
+ ![An illustration of people helping each other up a staircase][support]
35
35
 
36
- ![alt text][opt-in]
36
+ ![An illustration of a postal worker delivering a speech bubble to a mother and child][opt-in]
37
37
 
38
- ![alt text][404]
38
+ ![An illustration of a person stepping through an empty frame of an oversized web browser window][404]
39
39
 
40
- ![alt text][500]
40
+ ![An illustration of several small people standing around an oversized janitor's warning sign][500]
41
41
 
42
42
  </div>
43
43
 
44
- [login]: https://www.malvernpanalytical.com/resource/svg/login3.svg
44
+ [login]: https://p3.aprimocdn.net/malvernpanalytical/192d2a88-af78-4670-a752-b0b90110745b/login3_Original%20file.svg
45
45
  [thankyou]: https://p3.aprimocdn.net/malvernpanalytical/0cd71419-bc75-4b43-8c4d-af69010bf927/thankyou_Original%20file.svg
46
46
  [support]: https://p3.aprimocdn.net/malvernpanalytical/aef489f7-a3cc-4a0c-ad6c-af3300baaa3b/support3_Original%20file.svg
47
47
  [opt-in]: https://p3.aprimocdn.net/malvernpanalytical/383c6156-cefd-4d8e-a913-af6d00cebf8a/opt-in%20success%20v02_Original%20file.svg