mp-design-system 1.2.10 → 1.2.12

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 (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