@mozaic-ds/vue 0.35.0-beta.2 → 0.35.0-beta.4

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mozaic-ds/vue",
3
- "version": "0.35.0-beta.2",
3
+ "version": "0.35.0-beta.4",
4
4
  "description": "Vue.js implementation of Mozaic Design System",
5
5
  "author": "Adeo - Mozaic Design System",
6
6
  "scripts": {
@@ -312,6 +312,7 @@ export default {
312
312
  },
313
313
  clearListbox() {
314
314
  this.listboxValue = this.multiple ? [] : undefined;
315
+ this.$emit('change', this.listboxValue);
315
316
  this.$emit('clear');
316
317
  },
317
318
  onClear() {
@@ -261,9 +261,11 @@ export default {
261
261
  getSelectedItems(val) {
262
262
  const value = val ? val : this.listboxValue;
263
263
 
264
- const selectedItems = this.items.filter((item) =>
265
- value.includes(item[this.dataValueExpr])
266
- );
264
+ const selectedItems = this.items.filter((item) => {
265
+ return this.multiple
266
+ ? value.includes(item[this.dataValueExpr])
267
+ : value === item[this.dataValueExpr];
268
+ });
267
269
 
268
270
  return selectedItems;
269
271
  },
@@ -1,32 +1,25 @@
1
1
  <template>
2
- <div
3
- v-click-outside="onClickOutside"
4
- class="mc-listbox-options"
5
- :class="{ 'mc-listbox-options--fixed': hasDataTable }"
6
- :style="setStyles"
7
- >
2
+ <div v-click-outside="closeListbox" class="mc-listbox-options">
8
3
  <button
9
4
  ref="trigger"
10
5
  type="button"
11
6
  class="mc-listbox-options__trigger"
12
- @click="onSwitch($event)"
7
+ @click="onClickTrigger($event)"
13
8
  >
14
- <m-icon name="DisplayOptions24" :color="triggerIconColor" />
9
+ <MIcon :name="icon" :color="triggerIconColor" />
15
10
  <span class="mc-listbox-options__trigger-label">{{ triggerLabel }}</span>
16
11
  </button>
17
12
  <div
13
+ v-show="isOpen"
18
14
  ref="listbox"
19
15
  class="mc-listbox-options__container"
20
- :class="{
21
- 'is-open': isOpen,
22
- 'align-right': position == 'right',
23
- 'align-top': displayTop,
24
- }"
16
+ :class="classObjectListbox"
17
+ :style="styleObjectListbox"
25
18
  role="listbox"
26
19
  aria-labelledby="listbox"
27
20
  >
28
21
  <ul
29
- v-for="(list, i) in listItems"
22
+ v-for="(list, i) in getItems"
30
23
  :key="`list${i}`"
31
24
  class="mc-listbox-options__list"
32
25
  >
@@ -36,7 +29,7 @@
36
29
  class="mc-listbox-options__tile"
37
30
  :class="{ 'is-disabled': item.disabled }"
38
31
  >
39
- <m-icon
32
+ <MIcon
40
33
  v-if="item.icon"
41
34
  :name="item.icon"
42
35
  class="mc-listbox-options__icon"
@@ -64,11 +57,9 @@ import MIcon from '../icon/MIcon.vue';
64
57
 
65
58
  export default {
66
59
  name: 'MListBoxActions',
67
-
68
60
  components: {
69
61
  MIcon,
70
62
  },
71
-
72
63
  directives: {
73
64
  'click-outside': {
74
65
  bind(el, binding, vnode) {
@@ -84,7 +75,6 @@ export default {
84
75
  },
85
76
  },
86
77
  },
87
-
88
78
  props: {
89
79
  open: {
90
80
  type: Boolean,
@@ -106,72 +96,59 @@ export default {
106
96
  type: String,
107
97
  default: 'currentColor',
108
98
  },
99
+ icon: {
100
+ type: String,
101
+ default: 'DisplayOptions24',
102
+ },
109
103
  },
110
-
111
104
  data() {
112
105
  return {
113
106
  isOpen: this.open,
114
107
  displayTop: false,
115
- posTop: '0px',
116
- hasDataTable: false,
108
+ listboxTop: '0px',
109
+ listboxLeft: '0px',
117
110
  };
118
111
  },
119
112
 
120
113
  computed: {
121
- listItems: function () {
114
+ classObjectListbox() {
115
+ return {
116
+ 'is-open': this.isOpen,
117
+ 'align-right': this.position == 'right',
118
+ 'align-top': this.displayTop,
119
+ };
120
+ },
121
+ styleObjectListbox() {
122
+ return {
123
+ top: this.listboxTop,
124
+ left: this.listboxLeft,
125
+ };
126
+ },
127
+ getItems() {
122
128
  const hasNestedArray = this.items.filter(Array.isArray).length;
123
129
 
124
130
  if (hasNestedArray === 0) {
125
131
  const listItems = [];
126
132
  listItems.push(this.items);
133
+
127
134
  return [this.items];
128
135
  }
129
136
 
130
137
  return this.items;
131
138
  },
132
- setStyles() {
133
- return {
134
- '--listbox-top': this.hasDataTable ? this.posTop + 'px' : null,
135
- };
136
- },
137
139
  },
138
-
139
140
  mounted() {
140
- this.hasDataTable =
141
- this.$parent.$options._componentTag === 'm-data-table' ? true : false;
142
-
143
- if (this.hasDataTable) {
144
- this.$parent.$el
145
- .querySelector('.mc-data-table__body')
146
- .addEventListener('scroll', this.handleScroll);
147
- }
141
+ this.teleport(this.$refs.listbox);
142
+ },
143
+ created() {
144
+ window.addEventListener('scroll', this.closeListbox, {
145
+ capture: true,
146
+ });
148
147
  },
149
-
150
148
  destroyed() {
151
- if (this.hasDataTable) {
152
- this.$parent.$el
153
- .querySelector('.mc-data-table__body')
154
- .removeEventListener('scroll', this.handleScroll);
155
- }
149
+ window.removeEventListener('scroll', this.closeListbox);
156
150
  },
157
-
158
151
  methods: {
159
- onClickOutside() {
160
- this.isOpen = false;
161
- },
162
- onSwitch(e) {
163
- if (!this.isOpen) {
164
- if (this.$refs.listbox.clientHeight + e.clientY >= window.innerHeight) {
165
- this.displayTop = true;
166
- }
167
-
168
- if (this.hasDataTable) {
169
- const buttonSizes = this.$refs.trigger.getBoundingClientRect();
170
- this.posTop = buttonSizes.top + buttonSizes.height;
171
- }
172
- }
173
- this.isOpen = !this.isOpen;
174
- },
175
152
  onClickItem(item, listIndex, itemIndex) {
176
153
  const valToEmit = Object.assign(
177
154
  { listIndex: listIndex, itemIndex: itemIndex },
@@ -180,7 +157,35 @@ export default {
180
157
  this.$emit('update:itemSelected', valToEmit); // TODO: deprecated
181
158
  this.$emit('item-clicked', valToEmit);
182
159
  },
183
- handleScroll() {
160
+ onClickTrigger(e) {
161
+ this.$nextTick(() => {
162
+ if (this.$refs.listbox.clientHeight + e.clientY >= window.innerHeight) {
163
+ this.displayTop = true;
164
+ }
165
+ });
166
+
167
+ this.isOpen = !this.isOpen;
168
+
169
+ this.setListBoxPosition();
170
+ },
171
+ setListBoxPosition() {
172
+ const { top, left, height } = this.$refs.trigger.getBoundingClientRect();
173
+ const topValue = Math.floor(top) + Math.floor(height) + window.scrollY;
174
+ const leftValue = Math.floor(left);
175
+ this.listboxTop = `${topValue}px`;
176
+ this.listboxLeft = `${leftValue}px`;
177
+ },
178
+ teleport(elToMove, elTarget) {
179
+ const target = elTarget ?? document.body;
180
+
181
+ if (target && elToMove) {
182
+ target.append(elToMove);
183
+ }
184
+ },
185
+ closeListbox() {
186
+ if (!this.isOpen) {
187
+ return;
188
+ }
184
189
  this.isOpen = false;
185
190
  },
186
191
  },
@@ -191,8 +196,6 @@ export default {
191
196
  @import 'settings-tools/all-settings';
192
197
 
193
198
  .mc-listbox-options {
194
- $parent: &;
195
-
196
199
  display: inline-block;
197
200
  position: relative;
198
201
 
@@ -213,14 +216,16 @@ export default {
213
216
  }
214
217
 
215
218
  &__container {
216
- position: absolute;
217
- overflow-y: auto;
218
- opacity: 0;
219
- visibility: hidden;
220
- min-width: $mu800;
221
219
  background-color: $color-grey-000;
222
220
  border: 1px solid $color-grey-600;
223
221
  border-radius: 3px;
222
+ left: 0;
223
+ min-width: $mu800;
224
+ overflow-y: auto;
225
+ opacity: 0;
226
+ position: absolute;
227
+ visibility: hidden;
228
+ top: 100%;
224
229
 
225
230
  &.is-open {
226
231
  opacity: 1;
@@ -242,7 +247,6 @@ export default {
242
247
  }
243
248
 
244
249
  &__list {
245
- $parent: get-parent-selector(&);
246
250
  @include unstyle-list();
247
251
  margin: 0 auto;
248
252
  padding: 8px 0;
@@ -315,14 +319,5 @@ export default {
315
319
  color: #c61112;
316
320
  }
317
321
  }
318
-
319
- &--fixed {
320
- position: static;
321
-
322
- .mc-listbox-options__container {
323
- position: fixed;
324
- top: var(--listbox-top);
325
- }
326
- }
327
322
  }
328
323
  </style>