@mozaic-ds/vue 0.19.0 → 0.20.0-beta.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 (36) hide show
  1. package/dist/mozaic-vue.adeo.css +10 -10
  2. package/dist/mozaic-vue.adeo.umd.js +36901 -9156
  3. package/dist/mozaic-vue.common.js +36889 -9152
  4. package/dist/mozaic-vue.common.js.map +1 -1
  5. package/dist/mozaic-vue.css +1 -1
  6. package/dist/mozaic-vue.umd.js +36901 -9156
  7. package/dist/mozaic-vue.umd.js.map +1 -1
  8. package/dist/mozaic-vue.umd.min.js +3 -1
  9. package/dist/mozaic-vue.umd.min.js.map +1 -1
  10. package/package.json +8 -5
  11. package/src/components/autocomplete/MAutocomplete.vue +134 -97
  12. package/src/components/datatable/MDataTable.vue +9 -6
  13. package/src/components/icon/MIcon.vue +1 -2
  14. package/src/components/listbox/MListBox.vue +88 -42
  15. package/src/tokens/adeo/android/colors.xml +42 -38
  16. package/src/tokens/adeo/css/_variables.scss +42 -38
  17. package/src/tokens/adeo/css/root.scss +26 -22
  18. package/src/tokens/adeo/ios/StyleDictionaryColor.h +4 -0
  19. package/src/tokens/adeo/ios/StyleDictionaryColor.m +42 -38
  20. package/src/tokens/adeo/ios/StyleDictionaryColor.swift +42 -38
  21. package/src/tokens/adeo/js/tokens.js +42 -38
  22. package/src/tokens/adeo/js/tokensObject.js +144 -60
  23. package/src/tokens/adeo/scss/_tokens.scss +50 -42
  24. package/dist/fonts/LeroyMerlinSans-Web-Italic.1b652c01.woff2 +0 -0
  25. package/dist/fonts/LeroyMerlinSans-Web-Italic.e1daa96d.woff +0 -0
  26. package/dist/fonts/LeroyMerlinSans-Web-Light.abc49f3e.woff +0 -0
  27. package/dist/fonts/LeroyMerlinSans-Web-Light.fbea6009.woff2 +0 -0
  28. package/dist/fonts/LeroyMerlinSans-Web-LightItalic.01eca0b6.woff +0 -0
  29. package/dist/fonts/LeroyMerlinSans-Web-LightItalic.b0c55b75.woff2 +0 -0
  30. package/dist/fonts/LeroyMerlinSans-Web-Regular.ad6adbe4.woff +0 -0
  31. package/dist/fonts/LeroyMerlinSans-Web-Regular.fbf22a5a.woff2 +0 -0
  32. package/dist/fonts/LeroyMerlinSans-Web-SemiBold.a1cbb92f.woff +0 -0
  33. package/dist/fonts/LeroyMerlinSans-Web-SemiBold.a6ab3422.woff2 +0 -0
  34. package/dist/fonts/LeroyMerlinSans-Web-SemiBoldItalic.6bdb2efc.woff2 +0 -0
  35. package/dist/fonts/LeroyMerlinSans-Web-SemiBoldItalic.93f14f9f.woff +0 -0
  36. package/src/components/icon/icons.js +0 -18887
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mozaic-ds/vue",
3
- "version": "0.19.0",
3
+ "version": "0.20.0-beta.0",
4
4
  "description": "Vue.js implementation of Mozaic Design System",
5
5
  "author": "Adeo - Mozaic Design System",
6
6
  "scripts": {
@@ -23,10 +23,13 @@
23
23
  "postinstall.js"
24
24
  ],
25
25
  "dependencies": {
26
- "@mozaic-ds/css-dev-tools": "^1.29.1",
27
- "@mozaic-ds/icons": "^1.30.0",
28
- "@mozaic-ds/styles": "^1.30.0",
29
- "@mozaic-ds/web-fonts": "^1.22.0",
26
+ "@mozaic-ds/css-dev-tools": "1.29.1",
27
+ "@mozaic-ds/icons": "1.34.0",
28
+ "@mozaic-ds/styles": "1.33.0",
29
+ "@mozaic-ds/web-fonts": "1.22.0",
30
+ "@vue/composition-api": "^1.6.2",
31
+ "@vueuse/components": "^8.6.0",
32
+ "@vueuse/core": "^8.6.0",
30
33
  "core-js": "^3.18.3",
31
34
  "libphonenumber-js": "1.9.50",
32
35
  "postcss-scss": "^4.0.1",
@@ -3,37 +3,41 @@
3
3
  ref="autocomplete"
4
4
  class="mc-autocomplete"
5
5
  :class="{ 'mc-autocomplete--multi': multiple }"
6
- :style="tagStyle"
7
- @keyup.esc="isOpen = true"
8
6
  >
9
7
  <m-tag
10
- v-if="multiple && selectedItems().length > 0"
8
+ v-if="multiple && modelValue.length > 0"
11
9
  id="tag"
12
10
  type="removable"
13
- :label="selectedItems().length.toString() + ' ' + labelTag"
11
+ :label="selectedItems.length.toString() + ' ' + labelTag"
14
12
  class="mc-autocomplete__tag"
15
13
  size="s"
16
14
  @remove-tag="removeElementsFromList()"
17
15
  />
18
16
  <m-text-input
19
- v-model="itemDisplayed"
17
+ v-model="state.itemDisplayed"
20
18
  :placeholder="placeholder"
21
- text-input-field-class="mc-autocomplete__trigger"
19
+ class="mc-autocomplete__trigger"
22
20
  icon-position="left"
23
21
  icon="DisplaySearch48"
24
22
  autocomplete="off"
25
23
  :style="{ width: boxWidth + 'px' }"
26
- @input="filerList"
27
- @click="isOpen = true"
24
+ @update:modelValue="updateDropdown"
25
+ @change="$emit('input-change', $event.target.value)"
26
+ @click="state.open = true"
28
27
  />
29
28
  <m-list-box
30
- :open="isOpen"
31
- :items="sort ? orderedItems() : itemListForDropdown"
29
+ ref="listbox"
30
+ v-model="state.selected"
31
+ :open="state.open"
32
+ :items="sort ? orderedItems() : state.itemListForDropdown"
32
33
  :multiple="multiple"
33
34
  :empty-search-label="emptySearchLabel"
34
35
  :style="{ width: boxWidth + 'px' }"
35
- @update:itemSelected="updateList"
36
- @close-list-box="isOpen = false"
36
+ :data-key-expr="dataKeyExpr"
37
+ :data-text-expr="dataTextExpr"
38
+ :data-value-expr="dataValueExpr"
39
+ @update:modelValue="(selected) => updateList(selected)"
40
+ @close-list-box="state.open = false"
37
41
  >
38
42
  <template #item="{ item }">
39
43
  <slot name="item" :item="item"> </slot>
@@ -43,14 +47,31 @@
43
47
  </template>
44
48
 
45
49
  <script>
46
- import MTextInput from '../textinput/MTextInput.vue';
47
- import MTag from '../tags/MTag.vue';
50
+ import Vue from 'vue';
51
+ import VueCompositionAPI from '@vue/composition-api';
52
+ Vue.use(VueCompositionAPI);
53
+
54
+ import {
55
+ ref,
56
+ reactive,
57
+ onMounted,
58
+ computed,
59
+ nextTick,
60
+ } from '@vue/composition-api';
61
+
62
+ import { onClickOutside } from '@vueuse/core';
48
63
  import MListBox from '../listbox/MListBox.vue';
64
+ import MTag from '../tags/MTag.vue';
65
+ import MTextInput from '../textinput/MTextInput.vue';
49
66
 
50
67
  export default {
51
68
  name: 'MAutocomplete',
52
69
 
53
- components: { MListBox, MTag, MTextInput },
70
+ components: {
71
+ MListBox,
72
+ MTag,
73
+ MTextInput,
74
+ },
54
75
 
55
76
  props: {
56
77
  multiple: {
@@ -82,54 +103,55 @@ export default {
82
103
  type: String,
83
104
  default: '',
84
105
  },
85
- open: {
86
- type: Boolean,
87
- default: false,
106
+ modelValue: {
107
+ type: Array,
108
+ default: () => [],
88
109
  },
89
- },
90
- data() {
91
- return {
92
- itemListForDropdown: this.$props.items,
93
- selected: this.$props.items,
94
- itemDisplayed: '',
95
- isOpen: this.$props.open,
96
- tagWidth: '0px',
97
- boxWidth: '288px',
98
- };
99
- },
100
- computed: {
101
- tagStyle() {
102
- return {
103
- '--tag-width': this.tagWidth,
104
- };
110
+ dataKeyExpr: {
111
+ type: String,
112
+ default: 'id',
105
113
  },
106
- boxStyle() {
107
- return {
108
- '--box-width': this.boxWidth,
109
- };
114
+ dataTextExpr: {
115
+ type: String,
116
+ default: 'text',
110
117
  },
111
- },
112
- mounted() {
113
- this.selectedItems();
114
- this.tagWidthCalcul();
115
- this.boxWidthCalcul();
116
- },
117
- methods: {
118
- tagWidthCalcul() {
119
- this.$nextTick(() => {
120
- this.tagWidth =
121
- document && document.querySelector('.mc-autocomplete__tag')
122
- ? document.querySelector('.mc-autocomplete__tag').clientWidth + 'px'
123
- : '0px';
124
- });
118
+ dataSelectedExpr: {
119
+ type: String,
120
+ default: 'selected',
125
121
  },
126
- selectedItems() {
127
- return this.selected.filter((item) => {
128
- return item.selected;
129
- });
122
+ dataValueExpr: {
123
+ type: String,
124
+ default: 'text',
130
125
  },
131
- orderedItems() {
132
- this.itemListForDropdown.sort((a, b) => {
126
+ },
127
+
128
+ emits: ['update:modelValue', 'list-removed', 'list-filtered', 'input-change'],
129
+
130
+ setup(props, { emit }) {
131
+ const autocomplete = ref(null);
132
+ const listbox = ref(null);
133
+
134
+ const state = reactive({
135
+ open: false,
136
+ itemListForDropdown: props.items,
137
+ selected: [],
138
+ itemDisplayed: '',
139
+ tagWidth: '0px',
140
+ });
141
+
142
+ onMounted(() => {
143
+ manageTag();
144
+ });
145
+
146
+ const selectedItems = computed(() =>
147
+ state.selected.filter((item) => {
148
+ return item[props.dataValueExpr];
149
+ })
150
+ );
151
+
152
+ const orderedItems = () => {
153
+ // Order by selected then by id
154
+ return Array.from(state.itemListForDropdown).sort((a, b) => {
133
155
  if (a.selected === b.selected) {
134
156
  return a.id - b.id;
135
157
  } else if (a.selected < b.selected) {
@@ -138,52 +160,67 @@ export default {
138
160
  return -1;
139
161
  }
140
162
  });
141
- },
142
- updateList(list) {
143
- if (!this.$props.multiple && list) {
144
- this.itemDisplayed = list[0].text;
163
+ };
164
+
165
+ const boxWidth = computed(() =>
166
+ autocomplete.value ? autocomplete.value.clientWidth : ''
167
+ );
168
+
169
+ onClickOutside(listbox, () => (state.open = false));
170
+
171
+ const updateList = (list) => {
172
+ if (!props.multiple && list) {
173
+ state.itemDisplayed = list[0].value;
145
174
  } else {
146
- this.isOpen = true;
147
- this.selectedItems();
175
+ state.open = true;
176
+ // manageTag();
148
177
  }
149
- this.itemListForDropdown.forEach((elem) => {
150
- if (elem.id === list.id) {
151
- elem.selected = false;
152
- }
153
- });
154
- this.tagWidthCalcul();
155
- this.$emit(
156
- 'update:modelValue',
157
- this.$props.multiple ? this.selectedItems().value : list
158
- );
159
- },
160
- removeElementsFromList() {
161
- this.itemListForDropdown.forEach((elem) => {
162
- elem.selected = false;
163
- });
164
- this.selectedItems();
165
- this.tagWidthCalcul();
166
- this.$emit('list-removed');
167
- },
168
- filerList(value) {
169
- if (value.length && this.$props.filter) {
170
- this.$props.filter(value);
178
+ state.selected = list;
179
+ emit('update:modelValue', list);
180
+ };
181
+
182
+ const removeElementsFromList = () => {
183
+ state.selected = [];
184
+ // manageTag();
185
+ emit('update:modelValue', state.selected);
186
+ emit('list-removed');
187
+ };
188
+
189
+ const updateDropdown = (value) => {
190
+ if (value.length && props.filter) {
191
+ props.filter(value);
171
192
  } else if (value.length) {
172
- this.itemListForDropdown = this.itemListForDropdown.filter((item) =>
173
- item.text.toUpperCase().includes(value.toUpperCase())
193
+ state.itemListForDropdown = props.items.filter((item) =>
194
+ item[props.dataTextExpr].toUpperCase().includes(value.toUpperCase())
174
195
  );
175
196
  } else {
176
- this.itemListForDropdown = this.$props.items;
197
+ state.itemListForDropdown = props.items;
177
198
  }
178
- this.$emit('list-filtered', this.itemListForDropdown);
179
- },
180
- boxWidthCalcul() {
181
- this.$nextTick(() => {
182
- this.boxWidth = document.querySelector('.mc-autocomplete').clientWidth;
183
- console.log(this.boxWidth);
199
+ emit('update:modelValue', state.selected);
200
+ emit('list-filtered', state.itemListForDropdown);
201
+ };
202
+
203
+ const manageTag = () => {
204
+ nextTick(() => {
205
+ state.tagWidth =
206
+ document && document.querySelector('.mc-autocomplete__tag')
207
+ ? document.querySelector('.mc-autocomplete__tag').clientWidth + 'px'
208
+ : '0px';
184
209
  });
185
- return;
186
- },
210
+ };
211
+
212
+ return {
213
+ autocomplete,
214
+ listbox,
215
+ state,
216
+ selectedItems,
217
+ orderedItems,
218
+ boxWidth,
219
+ updateList,
220
+ removeElementsFromList,
221
+ updateDropdown,
222
+ manageTag,
223
+ };
187
224
  },
188
225
  };
189
226
  </script>
@@ -49,7 +49,11 @@
49
49
  allowRowClick && onRowClick({ event: $event, item: item })
50
50
  "
51
51
  >
52
- <slot :name="`item.${header.dataFieldExpr}`" :item="item" :index="rowIndex">
52
+ <slot
53
+ :name="`item.${header.dataFieldExpr}`"
54
+ :item="item"
55
+ :index="rowIndex"
56
+ >
53
57
  {{ getItemValue(item, header.dataFieldExpr) }}
54
58
  </slot>
55
59
  </td>
@@ -62,7 +66,10 @@
62
66
  </tbody>
63
67
  </table>
64
68
  </div>
65
- <div v-if="pagingOptions.enabled && total != null" class="mc-data-table__footer">
69
+ <div
70
+ v-if="pagingOptions.enabled && total != null"
71
+ class="mc-data-table__footer"
72
+ >
66
73
  <div class="mc-data-table__footer__item-per-page">
67
74
  <m-select
68
75
  :id="'itemPerPage'"
@@ -586,8 +593,6 @@ $local-config: (
586
593
 
587
594
  @import 'settings-tools/_all-settings';
588
595
 
589
- @include import-font-families();
590
-
591
596
  .mc-data-table {
592
597
  @include set-font-face();
593
598
 
@@ -706,8 +711,6 @@ $local-config: (
706
711
  @include set-border-radius('m', 'bottom');
707
712
 
708
713
  &__item-per-page {
709
- min-width: 100px;
710
-
711
714
  & select {
712
715
  width: auto;
713
716
  font-size: 0.875rem;
@@ -37,8 +37,7 @@ export default {
37
37
  return () =>
38
38
  import(
39
39
  /* webpackMode: 'eager' */
40
- // '@mozaic-ds/icons/js/icons.js'
41
- './icons.js' // <= example file
40
+ '@mozaic-ds/icons/js/icons.js'
42
41
  );
43
42
  },
44
43
 
@@ -1,41 +1,51 @@
1
1
  <template>
2
2
  <ul
3
- v-if="items.length > 0"
3
+ v-if="state.selectableItems.length > 0"
4
4
  ref="listbox"
5
5
  role="listbox"
6
- class="mc-listbox"
6
+ class="mc-listbox mc-listbox--multi"
7
7
  aria-labelledby="listbox"
8
- :class="{ 'is-open': open, 'mc-listbox--multi': multiple }"
8
+ :class="{ 'is-open': open }"
9
9
  >
10
10
  <li
11
- v-for="item in selectableItems"
12
- :key="item.id"
11
+ v-for="item in state.selectableItems"
12
+ :key="item[dataKeyExpr]"
13
13
  class="mc-listbox__item"
14
- @change="$emit('update:itemSelected', item)"
15
- @click.self="updateList(item.id, item.text, !item.selected, true)"
16
14
  >
17
15
  <slot name="item" :item="item">
18
- <span class="mc-listbox__text">{{ item.text }} </span>
16
+ <label
17
+ :for="`checkbox-dropdown-${item[dataKeyExpr]}-${uuid}`"
18
+ class="mc-listbox__label"
19
+ >{{ item[dataTextExpr] }}
20
+ </label>
19
21
  </slot>
20
22
  <m-checkbox
21
- v-if="multiple"
22
- :id="`checkbox-dropdown-${item.id}`"
23
- v-model="selectableItems.find((elem) => elem.id === item.id).selected"
23
+ :id="`checkbox-dropdown-${item[dataKeyExpr]}-${uuid}`"
24
+ :class="{ hideCheckbox: !multiple }"
24
25
  class="mc-listbox__input"
25
- @change="updateList(item.id, item.text, !item.selected, $e)"
26
+ :checked="updateModelValue(true, item)"
27
+ @update:modelValue="(v) => updateList(v, item[dataValueExpr])"
26
28
  />
27
29
  </li>
28
30
  </ul>
29
- <div v-else class="mc-list-box__empty">
31
+ <div v-else class="mc-listbox__empty">
30
32
  {{ emptySearchLabel }}
31
33
  </div>
32
34
  </template>
35
+
33
36
  <script>
37
+ import Vue from 'vue';
38
+ import VueCompositionAPI from '@vue/composition-api';
39
+ Vue.use(VueCompositionAPI);
40
+ import { reactive, watch, ref } from '@vue/composition-api';
34
41
  import MCheckbox from '../checkbox/MCheckbox.vue';
42
+
35
43
  export default {
36
44
  name: 'MListbox',
37
45
 
38
- components: { MCheckbox },
46
+ components: {
47
+ MCheckbox,
48
+ },
39
49
 
40
50
  props: {
41
51
  open: {
@@ -58,44 +68,80 @@ export default {
58
68
  type: Boolean,
59
69
  default: false,
60
70
  },
61
- },
62
- data() {
63
- return {
64
- selectableItems: null,
65
- selected: [],
66
- };
67
- },
68
- watch: {
69
- items: {
70
- handler: function (val) {
71
- this.selectableItems = val;
72
- },
73
- immediate: true,
71
+ dataKeyExpr: {
72
+ type: String,
73
+ default: 'id',
74
+ },
75
+ dataTextExpr: {
76
+ type: String,
77
+ default: 'text',
78
+ },
79
+ dataValueExpr: {
80
+ type: String,
81
+ default: 'text',
82
+ },
83
+ modelValue: {
84
+ type: Array,
85
+ default: () => [],
74
86
  },
75
87
  },
76
- methods: {
77
- updateList(id, text, value, isCheckboxUpdate) {
78
- if (!this.multiple) {
79
- this.$emit('update:itemSelected', [{ id, selected: value, text }]);
80
88
 
81
- this.$emit('close-list-box');
89
+ emits: ['update:itemSelected', 'close-list-box', 'update:modelValue'],
90
+
91
+ setup(props, { emit }) {
92
+ const listbox = ref(null);
93
+
94
+ let uuid = Math.random();
95
+
96
+ const state = reactive({
97
+ selectableItems: props.items,
98
+ selected: [],
99
+ });
100
+
101
+ const updateList = (checked, value) => {
102
+ if (!props.multiple) {
103
+ emit('update:modelValue', [{ value }]);
104
+ emit('close-list-box');
82
105
  return;
83
106
  }
84
107
 
85
- if (
86
- isCheckboxUpdate &&
87
- this.selectableItems.find((item) => item.id === id)
88
- ) {
89
- this.selectableItems.find((item) => item.id === id).selected = value;
108
+ if (checked) {
109
+ state.selected = [...state.selected, { [props.dataValueExpr]: value }];
110
+ } else {
111
+ state.selected = state.selected.filter(
112
+ (item) => item[props.dataValueExpr] !== value
113
+ );
90
114
  }
115
+ emit('update:modelValue', state.selected);
116
+ };
91
117
 
92
- if (value) {
93
- this.selected = [...this.selected, { id, selected: value, text }];
118
+ const updateModelValue = (checked, value) => {
119
+ state.selected = props.modelValue;
120
+ if (state.selected) {
121
+ return (
122
+ state.selected.filter(
123
+ (item) => item[props.dataValueExpr] === value[props.dataValueExpr]
124
+ ).length > 0
125
+ );
94
126
  } else {
95
- this.selected = this.selected.filter((item) => item.id !== id);
127
+ return undefined;
96
128
  }
97
- this.$emit('update:itemSelected', this.selectableItems);
98
- },
129
+ };
130
+
131
+ watch(
132
+ () => props.items,
133
+ (nextItems) => {
134
+ state.selectableItems = nextItems;
135
+ }
136
+ );
137
+
138
+ return {
139
+ listbox,
140
+ uuid,
141
+ state,
142
+ updateList,
143
+ updateModelValue,
144
+ };
99
145
  },
100
146
  };
101
147
  </script>