@madgex/design-system 1.55.1 → 1.56.1

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 (66) hide show
  1. package/coverage/cobertura-coverage.xml +57 -3
  2. package/coverage/components/accordion/accordion.js.html +1 -1
  3. package/coverage/components/accordion/index.html +1 -1
  4. package/coverage/components/inputs/combobox/combobox.js.html +1 -1
  5. package/coverage/components/inputs/combobox/index.html +1 -1
  6. package/coverage/components/inputs/combobox/vue-components/Combobox.vue.html +1 -1
  7. package/coverage/components/inputs/combobox/vue-components/ListBoxOption.vue.html +1 -1
  8. package/coverage/components/inputs/combobox/vue-components/index.html +1 -1
  9. package/coverage/components/inputs/file-upload/file-upload.js.html +1 -1
  10. package/coverage/components/inputs/file-upload/index.html +1 -1
  11. package/coverage/components/inputs/multi-select/index.html +1 -1
  12. package/coverage/components/inputs/multi-select/multi-select.js.html +1 -1
  13. package/coverage/components/inputs/multi-select/vue-components/MultiSelect.vue.html +1 -1
  14. package/coverage/components/inputs/multi-select/vue-components/MultiSelectCheckbox.vue.html +1 -1
  15. package/coverage/components/inputs/multi-select/vue-components/MultiSelectCheckboxGroup.vue.html +1 -1
  16. package/coverage/components/inputs/multi-select/vue-components/index.html +1 -1
  17. package/coverage/components/inputs/textarea/character-count.js.html +190 -0
  18. package/coverage/components/inputs/textarea/index.html +110 -0
  19. package/coverage/components/modal/index.html +1 -1
  20. package/coverage/components/modal/modal.js.html +1 -1
  21. package/coverage/components/notification/index.html +1 -1
  22. package/coverage/components/notification/notification.js.html +1 -1
  23. package/coverage/components/popover/index.html +1 -1
  24. package/coverage/components/popover/popover.js.html +1 -1
  25. package/coverage/components/switch-state/index.html +1 -1
  26. package/coverage/components/switch-state/switch-state.js.html +1 -1
  27. package/coverage/components/tabs/index.html +1 -1
  28. package/coverage/components/tabs/tabs.js.html +1 -1
  29. package/coverage/index.html +26 -11
  30. package/coverage/js/common.js.html +1 -1
  31. package/coverage/js/fractal-scripts/combobox.js.html +1 -1
  32. package/coverage/js/fractal-scripts/index.html +1 -1
  33. package/coverage/js/fractal-scripts/notification.js.html +1 -1
  34. package/coverage/js/fractal-scripts/switch-state.js.html +1 -1
  35. package/coverage/js/index-fractal.js.html +1 -1
  36. package/coverage/js/index-polyfills.js.html +1 -1
  37. package/coverage/js/index-vue.js.html +1 -1
  38. package/coverage/js/index.html +5 -5
  39. package/coverage/js/index.js.html +10 -4
  40. package/coverage/js/polyfills/closest.js.html +1 -1
  41. package/coverage/js/polyfills/index.html +1 -1
  42. package/coverage/js/polyfills/remove.js.html +1 -1
  43. package/coverage/tokens/_config.js.html +1 -1
  44. package/coverage/tokens/index.html +1 -1
  45. package/dist/_tokens/css/_tokens.css +1 -1
  46. package/dist/_tokens/js/_tokens-module.js +1 -1
  47. package/dist/_tokens/scss/_tokens.scss +1 -1
  48. package/dist/css/index.css +1 -1
  49. package/dist/js/index.js +6 -6
  50. package/package.json +1 -1
  51. package/src/components/inputs/_form-elements.scss +19 -1
  52. package/src/components/inputs/file-upload/README.md +9 -0
  53. package/src/components/inputs/textarea/README.md +39 -0
  54. package/src/components/inputs/textarea/_macro.njk +3 -0
  55. package/src/components/inputs/textarea/_template.njk +55 -0
  56. package/src/components/inputs/textarea/character-count.js +37 -0
  57. package/src/components/inputs/textarea/textarea.config.js +10 -0
  58. package/src/components/inputs/textarea/textarea.njk +24 -0
  59. package/src/components/inputs/textarea/textarea.scss +4 -0
  60. package/src/js/index.js +2 -0
  61. package/src/scss/components/__index.scss +1 -1
  62. package/src/components/textarea/_macro.njk +0 -3
  63. package/src/components/textarea/_template.njk +0 -41
  64. package/src/components/textarea/textarea.config.js +0 -31
  65. package/src/components/textarea/textarea.njk +0 -11
  66. package/src/components/textarea/textarea.scss +0 -7
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@madgex/design-system",
3
3
  "author": "Madgex",
4
4
  "license": "UNLICENSED",
5
- "version": "1.55.1",
5
+ "version": "1.56.1",
6
6
  "scripts": {
7
7
  "clean": "rimraf dist public tokens/build",
8
8
  "commit": "commit",
@@ -31,11 +31,29 @@
31
31
  .mds-form-message {
32
32
  @extend .mds-font-brevier;
33
33
  margin-bottom: $mds-size-baseline * 4;
34
+ display: flex;
35
+ align-items: center;
34
36
 
35
37
  &--error {
38
+ color: $mds-color-status-error-dark;
39
+ }
40
+ }
41
+
42
+ .mds-form-message--character-count {
43
+ display: none;
44
+ margin-top: $mds-size-baseline;
45
+
46
+ .js & {
36
47
  display: flex;
37
48
  align-items: center;
38
- color: $mds-color-status-error-dark;
49
+ justify-content: flex-end;
50
+ }
51
+
52
+ & .mds-icon {
53
+ display: none;
54
+ }
55
+ &.mds-form-message--error .mds-icon {
56
+ display: inline-block;
39
57
  }
40
58
  }
41
59
 
@@ -15,6 +15,7 @@
15
15
  - `state`: The current state of the input, currently the only allowed value is `error` **optional**,
16
16
  - `tooltipMessage`: Toggles a tooltip with this message to appear on the input **optional**
17
17
  - `classes`: add extra classes to the trigger - **optional**
18
+ - `fileTypes`: comma separated list of the different types of file you want to allow. It will add the `accept` attribute on the input - **optional ** (see notes on validation)
18
19
 
19
20
  ## Accessibility
20
21
 
@@ -31,6 +32,14 @@ For keyboard users as the file input itself remains visually hidden, when it rec
31
32
 
32
33
  The styling falls back completely to a native file input with default design system form field styling if Javascript is not available.
33
34
 
35
+ ## Validation
36
+
37
+ The `accept` attribute doesn't validate the types of the selected files; it simply provides hints for browsers to guide users towards selecting the correct file types. It is possible (in most cases) for users to toggle an option in the file chooser that makes it possible to override this and select any file they wish, which could have the incorrect type.
38
+
39
+ When using the drag and drop functionality, the user can also choose any file.
40
+
41
+ Because of this, you should make sure that expected requirements are validated server-side.
42
+
34
43
  ## Note
35
44
 
36
45
  When a file is selected, the drag & drop/file selection area is disabled. When using cloud services such as Dropbox or Google Drive, the buttons to access those services will disappear as well. The user will need to click on the "remove file" button to be able to select a file again, either using the file input or the cloud services.
@@ -0,0 +1,39 @@
1
+ ## Parameters
2
+
3
+ - `labelText`: The label for the textarea **required**,
4
+ - `hideLabel`: true/false - Add this parameter if you need to visually hide the label. The text of the label will the used by default as a placeholder, unless overridden by the placeholder parameter **optional**
5
+ **(please see accessibility notes below regarding the use of this parameter)**
6
+ - `name`: The name of the textarea field, uses ID unless specified **optional**,
7
+ - `id`: The id attribute of the field, **required**
8
+ - `optional`: Is the textarea optional, otherwise required **optional**,
9
+ - `disabled`: Should the textarea be disabled **optional**,
10
+ - `helpText`: Helper text to display under the label **optional**,
11
+ - `validationError`: The error message provided by validation **optional**,
12
+ - `state`: The current state of the textarea, currently the only allowed value is `error` **optional**,
13
+ - `tooltipMessage`: Toggles a tooltip with this message to appear on the textarea **optional**
14
+ - `classes`: add extra classes to the trigger - **optional**
15
+ - `placeholder`: add a placeholder to the textarea **optional**
16
+ **(please see accessibility notes below regarding the use of this parameter)**
17
+ - `maxlength`: specify the maximum length (in characters) allowed in the textarea. Adding this attribute will automatically add a "character counter" at the bottom right of the textarea (see notes below) - **optional**
18
+
19
+
20
+ ## Accessibility
21
+
22
+ This textarea relies entirely on the browser standard textarea and applies the accessibility provided by that.
23
+ Additional accessibility aria attributes are applied to the label `aria-live=polite` to inform users of help text or error messages attributed to a form
24
+
25
+ Avoid using `hideLabel` and `placeholder` if you can. Only hide the label when there can be no mistake as to what the textarea is for, probably when there is only one textarea in the form.
26
+ The placeholder can also be a problem given its lower contrast so don't rely on it to give important information. Use the `helpText` or the `tooltipMessage` instead, for example.
27
+
28
+ Useful article: https://www.nngroup.com/articles/form-design-placeholders/
29
+
30
+
31
+ ## Character counter
32
+ Adding the `maxlength` attribute will add a "character counter" automatically if javascript is enabled. Please note that the attribute will be removed with javascript to allow for a negative count. This is to ensure that the text entered by the user is not cut off without warning. The negative count's message will look like an error to prompt the user to edit the text entered. The maximum length of the text should obviously be checked server side.
33
+ Note: Line breaks are counted as 2 characters as forms will encode them as such (`\r\n`)
34
+
35
+ `aria-live="polite"` and `aria-atomic="true"` has been added to the counter container so the updates can be read to the user after he has finished entering the text.
36
+ We are also using `aria-describedby` to get the number of characters left when a user enter the textarea.
37
+
38
+ Please note that, at the date of writing (28/07/20), `aria-describedby` doesn't work if it references a `role="alert/status"` (https://a11ysupport.io/tech/aria/aria-describedby_attribute) which is why we're only using the `aria-live` and `aria-atomic` on the live region.
39
+
@@ -0,0 +1,3 @@
1
+ {% macro MdsTextarea(params) %}
2
+ {%- include "./_template.njk" -%}
3
+ {% endmacro %}
@@ -0,0 +1,55 @@
1
+ {% from "../label/_macro.njk" import MdsInputLabel %}
2
+ {% from "../_message/_macro.njk" import MdsInputMessages %}
3
+ {% from "../../icons/_macro.njk" import MdsIcon %}
4
+
5
+ {% if params.name %}
6
+ {% set name = params.name %}
7
+ {% else %}
8
+ {% set name = params.id %}
9
+ {% endif %}
10
+
11
+ <div class="mds-form-element mds-form-element--textarea{% if params.state %} mds-form-element--{{params.state}}{% endif %}{% if params.classes %} {{params.classes}}{% endif %}{% if params.maxlength %} mds-form-element--character-count{% endif %}" id="{{ params.id }}-container" data-test="textarea">
12
+ {{ MdsInputLabel({
13
+ labelText: params.labelText,
14
+ hideLabel: params.hideLabel,
15
+ id: params.id,
16
+ optional: params.optional,
17
+ tooltipMessage: params.tooltipMessage
18
+ }) }}
19
+ {{ MdsInputMessages({
20
+ id: params.id,
21
+ helpText: params.helpText,
22
+ validationError: params.validationError
23
+ }) }}
24
+ <textarea
25
+ class="mds-form-control"
26
+ name="{{ name }}"
27
+ id="{{ params.id }}"
28
+ {% if not params.optional %}
29
+ required="required"
30
+ {% endif %}
31
+ {% if params.disabled %}
32
+ disabled="disabled"
33
+ {% endif %}
34
+ {% if params.hideLabel or params.placeholder %}
35
+ placeholder="{% if params.placeholder %}{{ params.placeholder }}{% else %}{{ params.labelText }}{% endif %}"
36
+ {% endif %}
37
+ {% if params.maxlength %}
38
+ maxlength="{{ params.maxlength }}" aria-describedby="{{ params.id }}-character-count-text"
39
+ {% endif %}
40
+ >{#
41
+ #}{% if params.value %}{{params.value}}{% endif %}{#
42
+ #}</textarea>
43
+ {% if params.maxlength %}
44
+ <div class="mds-form-message mds-form-message--character-count" id="{{ params.id }}-character-count-text" aria-live="polite" aria-atomic="true">
45
+ {{- MdsIcon({
46
+ iconName: 'cross',
47
+ classes: 'mds-icon--sm',
48
+ hasContainer: true,
49
+ containerClasses: 'mds-icon-container--circle mds-icon-container--error mds-icon-container--before'
50
+ })
51
+ -}}
52
+ <span><span class="js-character-count-number">{{ params.maxlength }}</span> characters remaining</span>
53
+ </div>
54
+ {% endif %}
55
+ </div>
@@ -0,0 +1,37 @@
1
+ /* eslint-disable no-param-reassign */
2
+ const characterCountClass = '.mds-form-element--character-count';
3
+ const messageClass = '.mds-form-message--character-count';
4
+ const characterCountNumberClass = '.js-character-count-number';
5
+ const formControlClass = '.mds-form-control';
6
+
7
+ const characterCount = {
8
+ init: () => {
9
+ const elementsWithCharacterCount = Array.from(document.querySelectorAll(characterCountClass));
10
+ elementsWithCharacterCount.forEach((element) => {
11
+ const formControl = element.querySelector(formControlClass);
12
+ const maxLength = formControl.getAttribute('maxlength');
13
+ const message = element.querySelector(messageClass);
14
+ const characterCountNumber = element.querySelector(characterCountNumberClass);
15
+ formControl.removeAttribute('maxlength');
16
+ characterCount.updateCounter(formControl, maxLength, characterCountNumber, message);
17
+ formControl.addEventListener('keyup', (e) => {
18
+ e.stopPropagation();
19
+ characterCount.updateCounter(formControl, maxLength, characterCountNumber, message);
20
+ });
21
+ });
22
+ },
23
+ updateCounter: (formControl, maxLength, characterCountNumber, message) => {
24
+ // Counting new lines as 2 characters to plan for \r\n encoding
25
+ const newLines = formControl.value.match(/(\r\n|\n|\r)/g);
26
+ const currentCount = formControl.value.length + (newLines ? newLines.length : 0);
27
+ const remainingCount = maxLength - currentCount;
28
+ characterCountNumber.textContent = remainingCount;
29
+ if (remainingCount < 0) {
30
+ message.classList.add('mds-form-message--error');
31
+ } else {
32
+ message.classList.remove('mds-form-message--error');
33
+ }
34
+ },
35
+ };
36
+
37
+ export default characterCount;
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ title: 'Textarea',
3
+ status: 'wip',
4
+ context: {
5
+ labelText: 'Textarea',
6
+ name: 'Example Textarea',
7
+ id: 'example-textarea',
8
+ maxlength: 20,
9
+ },
10
+ };
@@ -0,0 +1,24 @@
1
+ {% from "./inputs/textarea/_macro.njk" import MdsTextarea %}
2
+
3
+ <div class="mds-grid-row">
4
+ <div class="mds-grid-col-12 mds-grid-col-md-6">
5
+ <div class="mds-form-field">
6
+ {{ MdsTextarea({
7
+ labelText: labelText,
8
+ hideLabel: hideLabel,
9
+ name: name,
10
+ id: id,
11
+ value:value,
12
+ optional: optional,
13
+ disabled: disabled,
14
+ placeholder: placeholder,
15
+ helpText: helpText,
16
+ validationError: validationError,
17
+ state: state,
18
+ classes: classes,
19
+ tooltipMessage: tooltipMessage,
20
+ maxlength: maxlength
21
+ }) }}
22
+ </div>
23
+ </div>
24
+ </div>
@@ -0,0 +1,4 @@
1
+ .mds-form-element--textarea .mds-form-control {
2
+ resize: vertical;
3
+ min-height: 150px;
4
+ }
package/src/js/index.js CHANGED
@@ -13,6 +13,7 @@ import accordion from '../components/accordion/accordion';
13
13
  import popovers from '../components/popover/popover';
14
14
  import modals from '../components/modal/modal';
15
15
  import fileUpload from '../components/inputs/file-upload/file-upload';
16
+ import characterCount from '../components/inputs/textarea/character-count';
16
17
 
17
18
  document.addEventListener('DOMContentLoaded', () => {
18
19
  tabs.init();
@@ -20,4 +21,5 @@ document.addEventListener('DOMContentLoaded', () => {
20
21
  popovers.init();
21
22
  modals.init();
22
23
  fileUpload.init();
24
+ characterCount.init();
23
25
  });
@@ -3,7 +3,6 @@
3
3
  @import '../../components/card/card';
4
4
  @import '../../components/section-title/section-title';
5
5
  @import '../../components/tabs/tabs';
6
- @import '../../components/textarea/textarea';
7
6
  @import '../../components/accordion/accordion';
8
7
  @import '../../components/pagination/pagination';
9
8
  @import '../../components/switch-state/switch-state';
@@ -13,5 +12,6 @@
13
12
  @import '../../components/inputs/combobox/combobox';
14
13
  @import '../../components/inputs/multi-select/multi-select';
15
14
  @import '../../components/inputs/file-upload/file-upload';
15
+ @import '../../components/inputs/textarea/textarea';
16
16
  @import '../../components/modal/modal';
17
17
  @import '../../components/skip-link/skip-link';
@@ -1,3 +0,0 @@
1
- {% macro MdsTextArea(params) %}
2
- {%- include "./_template.njk" -%}
3
- {% endmacro %}
@@ -1,41 +0,0 @@
1
- <div data-test="textarea">
2
- <label class="mds-display-block mds-input__label mds-font-long-primer mds-margin-bottom-b1" for="{{ params.id }}">
3
- {{ params.labelText }}
4
- {% if params.required %}
5
- <span>*</span>
6
- {% endif %}
7
- </label>
8
- {% if params.labelHint %}
9
- <span
10
- class="mds-display-block mds-input__label--hint mds-font-long-primer mds-margin-bottom-b1"
11
- id="{{ params.id }}-hint"
12
- >
13
- {{ params.labelHint }}
14
- </span>
15
- {% endif %}
16
- <textarea
17
- class="mds-textarea mds-border mds-border-radius"
18
- name="{{ params.name }}"
19
- id="{{ params.id }}"
20
- cols="{{ params.cols | default(30) }}"
21
- rows="{{ params.rows | default(10) }}"
22
- {% if params.labelHint or params.validationMessage %}
23
- aria-describedby="{% if params.labelHint %}{{ params.id }}-hint {% endif %}{% if params.validationMessage %}{{ params.id }}-validation-message{% endif %}"
24
- {% endif %}
25
- {% if params.disabled %}
26
- disabled="disabled"
27
- {% endif %}
28
- {% if params.required %}
29
- required="required"
30
- {% endif %}
31
- ></textarea>
32
- {% if params.validationMessage %}
33
- <span
34
- aria-live="polite"
35
- id="{{ params.id }}-validation-message"
36
- class="mds-input__validation-message mds-font-brevier"
37
- >
38
- {{ params.validationMessage }}
39
- </span>
40
- {% endif %}
41
- </div>
@@ -1,31 +0,0 @@
1
- module.exports = {
2
- title: 'Text Area',
3
- status: 'prototype',
4
- context: {
5
- labelText: 'Text area',
6
- name: 'Example text area',
7
- id: 'exampleTextArea',
8
- },
9
- variants: [
10
- {
11
- name: 'With label hint',
12
- context: {
13
- labelText: 'Hint input',
14
- name: 'Hint input',
15
- id: 'hintInput',
16
- type: 'text',
17
- labelHint: 'This is a text area',
18
- },
19
- },
20
- {
21
- name: 'With validation message',
22
- context: {
23
- labelText: 'Validated input',
24
- name: 'Validated input',
25
- id: 'validatedInput',
26
- type: 'text',
27
- validationMessage: '100 characters remaining',
28
- },
29
- },
30
- ],
31
- };
@@ -1,11 +0,0 @@
1
- {% from "./textarea/_macro.njk" import MdsTextArea %}
2
-
3
- {{ MdsTextArea({
4
- labelText: labelText,
5
- labelHint: labelHint,
6
- name: name,
7
- id: id,
8
- required: required,
9
- disabled: disabled,
10
- validationMessage: validationMessage
11
- }) }}
@@ -1,7 +0,0 @@
1
- .mds-textarea {
2
- resize: none;
3
- width: 100%;
4
- background-color: $mds-color-neutral-lightest;
5
- margin: $mds-size-baseline 0;
6
- padding: $mds-size-baseline * 2;
7
- }