@madgex/design-system 3.1.2 → 3.2.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 (55) hide show
  1. package/coverage/cobertura-coverage.xml +80 -67
  2. package/coverage/components/accordion/accordion.js.html +1 -1
  3. package/coverage/components/accordion/index.html +1 -1
  4. package/coverage/components/button/button.js.html +1 -1
  5. package/coverage/components/button/index.html +1 -1
  6. package/coverage/components/inputs/combobox/combobox.js.html +1 -1
  7. package/coverage/components/inputs/combobox/index.html +1 -1
  8. package/coverage/components/inputs/combobox/vue-components/Combobox.vue.html +1 -1
  9. package/coverage/components/inputs/combobox/vue-components/ListBoxOption.vue.html +1 -1
  10. package/coverage/components/inputs/combobox/vue-components/index.html +1 -1
  11. package/coverage/components/inputs/file-upload/file-upload.js.html +1 -1
  12. package/coverage/components/inputs/file-upload/index.html +1 -1
  13. package/coverage/components/inputs/textarea/character-count.js.html +1 -1
  14. package/coverage/components/inputs/textarea/index.html +1 -1
  15. package/coverage/components/modal/index.html +1 -1
  16. package/coverage/components/modal/modal.js.html +1 -1
  17. package/coverage/components/notification/index.html +1 -1
  18. package/coverage/components/notification/notification.js.html +1 -1
  19. package/coverage/components/popover/index.html +1 -1
  20. package/coverage/components/popover/popover.js.html +1 -1
  21. package/coverage/components/switch-state/index.html +1 -1
  22. package/coverage/components/switch-state/switch-state.js.html +1 -1
  23. package/coverage/components/tabs/index.html +9 -9
  24. package/coverage/components/tabs/tabs.js.html +53 -14
  25. package/coverage/index.html +13 -13
  26. package/coverage/js/common.js.html +1 -1
  27. package/coverage/js/fractal-scripts/combobox.js.html +1 -1
  28. package/coverage/js/fractal-scripts/index.html +1 -1
  29. package/coverage/js/fractal-scripts/notification.js.html +1 -1
  30. package/coverage/js/fractal-scripts/switch-state.js.html +1 -1
  31. package/coverage/js/index-fractal.js.html +1 -1
  32. package/coverage/js/index-polyfills.js.html +1 -1
  33. package/coverage/js/index-vue.js.html +1 -1
  34. package/coverage/js/index.html +1 -1
  35. package/coverage/js/index.js.html +1 -1
  36. package/coverage/js/polyfills/arrayPrototypeFind.js.html +1 -1
  37. package/coverage/js/polyfills/closest.js.html +1 -1
  38. package/coverage/js/polyfills/index.html +1 -1
  39. package/coverage/js/polyfills/objectAssign.js.html +1 -1
  40. package/coverage/js/polyfills/remove.js.html +1 -1
  41. package/coverage/tokens/_config.js.html +1 -1
  42. package/coverage/tokens/index.html +1 -1
  43. package/dist/_tokens/css/_tokens.css +1 -1
  44. package/dist/_tokens/js/_tokens-module.js +1 -1
  45. package/dist/_tokens/scss/_tokens.scss +1 -1
  46. package/dist/css/index.css +1 -1
  47. package/dist/js/index.js +1 -1
  48. package/package.json +1 -1
  49. package/src/components/tabs/README.md +4 -0
  50. package/src/components/tabs/_template.njk +26 -30
  51. package/src/components/tabs/tab-id.njk +13 -0
  52. package/src/components/tabs/tabs.config.js +28 -9
  53. package/src/components/tabs/tabs.js +20 -7
  54. package/src/components/tabs/tabs.njk +8 -5
  55. package/src/components/tabs/tabs.scss +67 -28
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@madgex/design-system",
3
3
  "author": "Madgex",
4
4
  "license": "UNLICENSED",
5
- "version": "3.1.2",
5
+ "version": "3.2.0",
6
6
  "scripts": {
7
7
  "clean": "rimraf dist public tokens/build",
8
8
  "commit": "commit",
@@ -2,8 +2,12 @@
2
2
 
3
3
  - `name`: the name you want to use to differentiate the component
4
4
  - `classes`: add extra CSS classes to the component
5
+ - `headerTag`: the html tag to use for the panel header (h2 as default)
5
6
  - `content`: is an array of objects containing [label, selected, id, content] for each tab, the content for the panel can also be a custom component
6
7
 
8
+ ## Variations
9
+ Tabs have different style depending on the amount of items to display, if 2 tabs then it will always display tabs (except when js is disabled), if more than 2 then it will display a list of links for small devices and tabs for desktop
10
+
7
11
 
8
12
  ## Accessibility
9
13
 
@@ -1,25 +1,20 @@
1
- {% if params.content %}
1
+ {% from "./tab-id.njk" import TabId %}
2
2
 
3
+ {% if params.content %}
3
4
  {% set kebabName -%}
4
5
  {{- params.name | lower | trim | replace(' ', '-') -}}
5
6
  {%- endset %}
6
- <div class="mds-tabs{%- if params.name %} mds-tabs--{{ kebabName }}{%- endif -%}{% if params.classes %} {{ params.classes }}{% endif %}" data-test="tabs-{{kebabName}}">
7
+ {% set tabVariation -%}
8
+ {%- if params.content.length > 2 -%}
9
+ js-desktop-tabbed
10
+ {%- else -%}
11
+ mds-tabs--full-tabbed js-full-tabbed
12
+ {%- endif -%}
13
+ {%- endset %}
14
+ <div class="mds-tabs {{ tabVariation }}{%- if params.name %} mds-tabs--{{ kebabName }}{%- endif -%}{% if params.classes %} {{ params.classes }}{% endif %}" data-test="tabs-{{kebabName}}">
7
15
  <ul class="mds-tabs__list">
8
16
  {%- for item in params.content -%}
9
- {%- set tabId %}
10
- {%- if item.id -%}
11
- {{ item.id }}
12
- {%- else -%}
13
- {#
14
- if the id is missing it will be constructed using:
15
- [component name]-[item label]-[index]
16
- e.g. period-next-week-2
17
- #}
18
- {%- if params.name -%}{{ kebabName }}-{%- endif -%}
19
- {{ item.label | lower | trim | replace(' ', '-') }}-{{loop.index}}
20
- {%- endif -%}
21
- {% endset -%}
22
-
17
+ {%- set tabId = TabId(item, params, loop.index) %}
23
18
  <li class="mds-tabs__list-item">
24
19
  <a href="#{{ tabId }}" class="mds-tabs__tab{%- if item.selected %} mds-tabs__tab--selected{%- endif %} js-tabs-item" data-test="tabs-trigger{% if tabId %}-{{tabId}}{% endif %}">
25
20
  {{- item.label -}}
@@ -28,21 +23,22 @@
28
23
  {%- endfor -%}
29
24
  </ul>
30
25
  {%- for item in params.content -%}
31
- {%- set tabPanelId %}
32
- {%- if item.id -%}
33
- {{ item.id }}
34
- {%- else -%}
35
- {#
36
- if the id is missing it will be constructed using:
37
- [component name]-[item label]-[index]
38
- e.g. period-next-week-2
39
- #}
40
- {%- if params.name -%}{{ kebabName }}-{%- endif -%}
41
- {{ item.label | lower | trim | replace(' ', '-') }}-{{loop.index}}
42
- {%- endif -%}
43
- {% endset -%}
26
+ {%- set tabId = TabId(item, params, loop.index) %}
27
+ {%- set headerTag -%}
28
+ {%- if params.headerTag -%}
29
+ {{- params.headerTag -}}
30
+ {%- else -%}
31
+ h2
32
+ {%- endif -%}
33
+ {%- endset -%}
44
34
 
45
- <section class="mds-tabs__panel{%- if not item.selected %} mds-tabs__panel--hidden {%- endif -%}{% if item.contentClasses %} {{ item.contentClasses }}{% endif %}" id="{{ tabPanelId }}" data-test="tab-panel{% if tabPanelId %}-{{tabPanelId}}{% endif %}">{{ item.content | safe }}</section>
35
+ <section class="mds-tabs__panel{%- if not item.selected %} mds-tabs__panel--hidden {%- endif -%}{% if item.contentClasses %} {{ item.contentClasses }}{% endif %}" id="{{ tabId }}" data-test="tab-panel{% if tabId %}-{{tabId}}{% endif %}">
36
+ {# id is used in js to apply aria-labelledby, don't forget to update both if needed #}
37
+ <{{headerTag}} id="label-{{tabId}}" class="mds-tabs__panel__header">{{- item.label -}}</{{headerTag}}>
38
+ <div class="mds-tabs__panel__content">
39
+ {{ item.content | safe }}
40
+ </div>
41
+ </section>
46
42
  {%- endfor -%}
47
43
  </div>
48
44
  {% endif %}
@@ -0,0 +1,13 @@
1
+ {%- macro TabId(item, params, loopIndex) -%}
2
+ {%- if item.id -%}
3
+ {{ item.id }}
4
+ {%- else -%}
5
+ {#
6
+ if the id is missing it will be constructed using:
7
+ [component name]-[item label]-[index]
8
+ e.g. period-next-week-2
9
+ #}
10
+ {%- if params.name -%}{{ kebabName }}-{%- endif -%}
11
+ {{ item.label | lower | trim | replace(' ', '-') }}-{{loopIndex}}
12
+ {%- endif -%}
13
+ {%- endmacro -%}
@@ -10,51 +10,70 @@ module.exports = {
10
10
  selected: true,
11
11
  id: 'today',
12
12
  content:
13
- '<strong>Daily menu:</strong><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero. Donec commodo elementum ligula, vel posuere purus tempor sit amet.</p>',
13
+ '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero. Donec commodo elementum ligula, vel posuere purus tempor sit amet.</p>',
14
14
  },
15
15
  {
16
16
  label: 'Tomorrow',
17
17
  id: 'tomorrow',
18
18
  content:
19
- '<strong>Tomorrow Tab:</strong><p><strong>Tomorrow</strong>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero.</p>',
19
+ '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero.</p>',
20
20
  },
21
21
  {
22
22
  label: 'Next week',
23
23
  id: 'next-week',
24
- content:
25
- '<strong>Next week:</strong><ul><li>Lorem</li><li>ipsum</li><li>dolor</li><li>sit</li><li>amet</li></ul><p>next week</p>',
24
+ content: '<ul><li>Lorem</li><li>ipsum</li><li>dolor</li><li>sit</li><li>amet</li></ul><p>next week</p>',
26
25
  contentClasses: 'mds-edited-text',
27
26
  },
28
27
  {
29
28
  label: 'Next month',
30
29
  id: 'next-month',
31
30
  content:
32
- '<strong>Next month:</strong><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero.</p>',
31
+ '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero.</p>',
33
32
  },
34
33
  ],
35
34
  },
36
35
  variants: [
36
+ {
37
+ name: 'Two Items',
38
+ context: {
39
+ name: 'Two Items',
40
+ classes: '',
41
+ content: [
42
+ {
43
+ label: 'Item 1',
44
+ selected: true,
45
+ content:
46
+ '<strong>Item 1 panel:</strong><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero. Donec commodo elementum ligula, vel posuere purus tempor sit amet.</p>',
47
+ },
48
+ {
49
+ label: 'Item 2',
50
+ content:
51
+ '<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero.</p>',
52
+ },
53
+ ],
54
+ },
55
+ },
37
56
  {
38
57
  name: 'No Ids',
39
58
  context: {
40
59
  name: 'Wild Pets',
41
60
  classes: '',
61
+ headerTag: 'h3',
42
62
  content: [
43
63
  {
44
64
  label: 'Dogs',
45
65
  selected: true,
46
66
  content:
47
- '<strong>Dogs panel:</strong><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero. Donec commodo elementum ligula, vel posuere purus tempor sit amet.</p>',
67
+ '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero. Donec commodo elementum ligula, vel posuere purus tempor sit amet.</p>',
48
68
  },
49
69
  {
50
70
  label: 'Cats',
51
71
  content:
52
- '<strong>Cats Tab:</strong><p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero.</p>',
72
+ '<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla magna ex, lobortis in luctus quis, viverra eu libero.</p>',
53
73
  },
54
74
  {
55
75
  label: 'Seagulls',
56
- content:
57
- '<strong>Seagulls:</strong><ul><li>Lorem</li><li>ipsum</li><li>dolor</li><li>sit</li><li>amet</li></ul><p>next week</p>',
76
+ content: '<ul><li>Lorem</li><li>ipsum</li><li>dolor</li><li>sit</li><li>amet</li></ul><p>next week</p>',
58
77
  contentClasses: 'mds-edited-text',
59
78
  },
60
79
  ],
@@ -1,3 +1,5 @@
1
+ const tokens = require('../../tokens/size.json');
2
+
1
3
  const tabsItemJsClass = 'js-tabs-item';
2
4
  const tabsClass = 'mds-tabs';
3
5
  const tabsListClass = 'mds-tabs__list';
@@ -7,14 +9,25 @@ const tabsTabClass = 'mds-tabs__tab';
7
9
  const tabsTabSelectedClass = 'mds-tabs__tab--selected';
8
10
  const tabsPanelHiddenClass = 'mds-tabs__panel--hidden';
9
11
  const tabsKeys = { left: 37, right: 39, up: 38, down: 40 };
12
+ const tabbedDesktop = '.js-desktop-tabbed';
13
+ const tabbedFull = '.js-full-tabbed';
14
+ const breakpoint = parseInt(tokens.size.breakpoint.lg.value, 10);
10
15
 
11
16
  const tabs = {
12
17
  init: () => {
13
- // Setting aria
14
- const tabsLists = Array.from(document.querySelectorAll(`.${tabsListClass}`));
15
- const tabsListItems = Array.from(document.querySelectorAll(`.${tabsListItemClass}`));
16
- const tabsTabs = Array.from(document.querySelectorAll(`.${tabsTabClass}`));
17
- const tabsPanel = Array.from(document.querySelectorAll(`.${tabsPanelClass}`));
18
+ tabs.setTabs(tabbedFull);
19
+
20
+ const screenWidth = window.innerWidth;
21
+
22
+ if (screenWidth > breakpoint) {
23
+ tabs.setTabs(tabbedDesktop);
24
+ }
25
+ },
26
+ setTabs: (classSelector) => {
27
+ const tabsTabs = Array.from(document.querySelectorAll(`${classSelector} .${tabsTabClass}`));
28
+ const tabsLists = Array.from(document.querySelectorAll(`${classSelector} .${tabsListClass}`));
29
+ const tabsListItems = Array.from(document.querySelectorAll(`${classSelector} .${tabsListItemClass}`));
30
+ const tabsPanel = Array.from(document.querySelectorAll(`${classSelector} .${tabsPanelClass}`));
18
31
 
19
32
  tabsLists.forEach((element) => {
20
33
  element.setAttribute('role', 'tablist');
@@ -34,10 +47,10 @@ const tabs = {
34
47
  });
35
48
  tabsPanel.forEach((element) => {
36
49
  element.setAttribute('role', 'tabpanel');
37
- element.setAttribute('aria-labelledby', element.attributes.id.value);
50
+ element.setAttribute('aria-labelledby', `label-${element.attributes.id.value}`);
38
51
  });
39
52
 
40
- const tabsItemsJs = document.querySelectorAll(`.${tabsItemJsClass}`);
53
+ const tabsItemsJs = document.querySelectorAll(`${classSelector} .${tabsItemJsClass}`);
41
54
  const tabsItemsJsArray = Array.from(tabsItemsJs);
42
55
 
43
56
  tabsItemsJsArray.forEach((element) => {
@@ -1,7 +1,10 @@
1
1
  {% from "./tabs/_macro.njk" import MdsTabs %}
2
2
 
3
- {{ MdsTabs({
4
- name: name,
5
- classes: classes,
6
- content: content
7
- }) }}
3
+ <div class="mds-surface mds-margin-bottom-b5">
4
+ {{ MdsTabs({
5
+ name: name,
6
+ classes: classes,
7
+ headerTag: headerTag,
8
+ content: content
9
+ }) }}
10
+ </div>
@@ -1,51 +1,90 @@
1
- .js .mds-tabs__panel--hidden {
2
- display: none;
3
- }
4
-
5
1
  .mds-tabs__list {
6
- margin-bottom: $mds-size-baseline * 2;
2
+ margin-bottom: 0;
3
+ padding-top: $mds-size-baseline * 3;
4
+ padding-bottom: $mds-size-baseline * 3;
7
5
  @extend .mds-border-bottom;
6
+ }
8
7
 
9
- .js & {
10
- margin-bottom: 0;
8
+ .mds-tabs__panel {
9
+ &:not(:last-child) {
10
+ @extend .mds-border-bottom;
11
+ }
12
+ &__header {
13
+ @extend .mds-surface__inner;
14
+ @extend .mds-border-bottom;
15
+ @extend .mds-font-great-primer;
16
+ padding-top: $mds-size-baseline * 3;
17
+ padding-bottom: $mds-size-baseline * 3;
18
+ background: $mds-color-neutral-lightest;
19
+ }
20
+ &__content {
21
+ @extend .mds-surface__inner;
11
22
  }
12
23
  }
13
24
 
14
- .js .mds-tabs__list-item {
15
- display: inline-block;
16
- width: 50%;
25
+ .mds-tabs__list-item {
17
26
  @extend .mds-font-great-primer;
18
-
19
- @include mq($from: $mds-size-breakpoint-md) {
20
- width: auto;
21
- }
22
27
  }
23
28
 
24
29
  .mds-tabs__tab {
25
30
  display: inline-block;
26
31
  @extend .mds-surface__inner;
27
- padding-top: $mds-size-baseline;
28
- padding-bottom: $mds-size-baseline;
32
+ padding-top: $mds-size-baseline * 2;
33
+ padding-bottom: $mds-size-baseline * 2;
34
+ }
35
+
36
+ // MIXIN to share between the 2 variations
37
+ @mixin tabbed-items {
38
+ .mds-tabs__list {
39
+ padding: 0;
40
+ }
41
+
42
+ .mds-tabs__list-item {
43
+ display: inline-block;
44
+ width: auto;
45
+ }
46
+
47
+ .mds-tabs__panel__header {
48
+ @include mds-visually-hidden;
49
+ }
50
+
51
+ .mds-tabs__panel--hidden {
52
+ display: none;
53
+ }
29
54
 
30
- .js & {
55
+ .mds-tabs__tab {
31
56
  width: 100%;
32
57
  text-decoration: none;
33
- text-align: center;
58
+ text-align: left;
34
59
  margin-right: $mds-size-baseline;
35
60
  padding-top: $mds-size-baseline * 6;
36
61
  padding-bottom: $mds-size-baseline * 5;
37
-
38
- @include mq($from: $mds-size-breakpoint-md) {
39
- text-align: left;
40
- }
41
62
  }
42
- }
43
63
 
44
- .js .mds-tabs__tab.mds-tabs__tab--selected {
45
- border-bottom: 6px solid $mds-color-link-base;
46
- color: $mds-color-text-headers-base;
64
+ .mds-tabs__tab.mds-tabs__tab--selected {
65
+ border-bottom: 6px solid $mds-color-link-base;
66
+ color: $mds-color-text-headers-base;
67
+ }
47
68
  }
48
69
 
49
- .mds-tabs__panel {
50
- @extend .mds-surface__inner;
70
+ .js {
71
+ // DEFAULT (desktop-tabbed)
72
+ @include mq($from: $mds-size-breakpoint-lg) {
73
+ @include tabbed-items;
74
+ }
75
+ // FULL-TABBED
76
+ .mds-tabs--full-tabbed {
77
+ @include tabbed-items;
78
+ .mds-tabs__list-item {
79
+ @include mq($from: $mds-size-breakpoint-md) {
80
+ width: auto;
81
+ }
82
+ }
83
+ .mds-tabs__tab {
84
+ text-align: center;
85
+ @include mq($from: $mds-size-breakpoint-md) {
86
+ text-align: left;
87
+ }
88
+ }
89
+ }
51
90
  }