@mozaic-ds/vue 0.35.0-beta.3 → 0.35.0-beta.5

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.3",
3
+ "version": "0.35.0-beta.5",
4
4
  "description": "Vue.js implementation of Mozaic Design System",
5
5
  "author": "Adeo - Mozaic Design System",
6
6
  "scripts": {
@@ -23,6 +23,7 @@
23
23
  "postinstall.js"
24
24
  ],
25
25
  "dependencies": {
26
+ "@linusborg/vue-simple-portal": "^0.1.5",
26
27
  "@mozaic-ds/css-dev-tools": "1.50.0",
27
28
  "@mozaic-ds/icons": "1.49.0",
28
29
  "@mozaic-ds/styles": "1.51.0",
@@ -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
  },
@@ -4,61 +4,70 @@
4
4
  ref="trigger"
5
5
  type="button"
6
6
  class="mc-listbox-options__trigger"
7
- @click="onClickTrigger($event)"
7
+ @click="onClickTrigger"
8
8
  >
9
9
  <MIcon :name="icon" :color="triggerIconColor" />
10
10
  <span class="mc-listbox-options__trigger-label">{{ triggerLabel }}</span>
11
11
  </button>
12
- <div
13
- v-show="isOpen"
14
- ref="listbox"
15
- class="mc-listbox-options__container"
16
- :class="classObjectListbox"
17
- :style="styleObjectListbox"
18
- role="listbox"
19
- aria-labelledby="listbox"
20
- >
21
- <ul
22
- v-for="(list, i) in getItems"
23
- :key="`list${i}`"
24
- class="mc-listbox-options__list"
25
- >
26
- <li
27
- v-for="(item, j) in list"
28
- :key="`item${j}`"
29
- class="mc-listbox-options__tile"
30
- :class="{ 'is-disabled': item.disabled }"
12
+ <Portal>
13
+ <transition @after-enter="onAfterEnter">
14
+ <div
15
+ v-if="isOpen"
16
+ ref="listbox"
17
+ class="mc-listbox-options__container"
18
+ :class="classObjectListbox"
19
+ :style="styleObjectListbox"
20
+ role="listbox"
21
+ aria-labelledby="listbox"
31
22
  >
32
- <MIcon
33
- v-if="item.icon"
34
- :name="item.icon"
35
- class="mc-listbox-options__icon"
36
- :color="item.danger ? '#C61112' : '#71706B'"
37
- />
38
- <component
39
- :is="item.href ? 'a' : 'button'"
40
- :href="item.href ? item.href : null"
41
- :type="item.href ? null : 'button'"
42
- :disabled="item.disabled ? true : null"
43
- class="mc-listbox-options__item"
44
- :class="{ 'is-danger': item.danger, 'is-disabled': item.disabled }"
45
- @click.self="onClickItem(item, i, j)"
23
+ <ul
24
+ v-for="(list, i) in getItems"
25
+ :key="`list${i}`"
26
+ class="mc-listbox-options__list"
46
27
  >
47
- {{ item.text }}
48
- </component>
49
- </li>
50
- </ul>
51
- </div>
28
+ <li
29
+ v-for="(item, j) in list"
30
+ :key="`item${j}`"
31
+ class="mc-listbox-options__tile"
32
+ :class="{ 'is-disabled': item.disabled }"
33
+ >
34
+ <MIcon
35
+ v-if="item.icon"
36
+ :name="item.icon"
37
+ class="mc-listbox-options__icon"
38
+ :color="item.danger ? '#C61112' : '#71706B'"
39
+ />
40
+ <component
41
+ :is="item.href ? 'a' : 'button'"
42
+ :href="item.href ? item.href : null"
43
+ :type="item.href ? null : 'button'"
44
+ :disabled="item.disabled ? true : null"
45
+ class="mc-listbox-options__item"
46
+ :class="{
47
+ 'is-danger': item.danger,
48
+ 'is-disabled': item.disabled,
49
+ }"
50
+ @click.self="onClickItem(item, i, j)"
51
+ >
52
+ {{ item.text }}
53
+ </component>
54
+ </li>
55
+ </ul>
56
+ </div>
57
+ </transition>
58
+ </Portal>
52
59
  </div>
53
60
  </template>
54
61
 
55
62
  <script>
63
+ import { Portal } from '@linusborg/vue-simple-portal';
56
64
  import MIcon from '../icon/MIcon.vue';
57
65
 
58
66
  export default {
59
67
  name: 'MListBoxActions',
60
68
  components: {
61
69
  MIcon,
70
+ Portal,
62
71
  },
63
72
  directives: {
64
73
  'click-outside': {
@@ -104,16 +113,16 @@ export default {
104
113
  data() {
105
114
  return {
106
115
  isOpen: this.open,
116
+ isVisible: false,
107
117
  displayTop: false,
108
118
  listboxTop: '0px',
109
119
  listboxLeft: '0px',
110
120
  };
111
121
  },
112
-
113
122
  computed: {
114
123
  classObjectListbox() {
115
124
  return {
116
- 'is-open': this.isOpen,
125
+ 'is-open': this.isVisible,
117
126
  'align-right': this.position == 'right',
118
127
  'align-top': this.displayTop,
119
128
  };
@@ -137,9 +146,6 @@ export default {
137
146
  return this.items;
138
147
  },
139
148
  },
140
- mounted() {
141
- this.teleport(this.$refs.listbox);
142
- },
143
149
  created() {
144
150
  window.addEventListener('scroll', this.closeListbox, {
145
151
  capture: true,
@@ -157,29 +163,21 @@ export default {
157
163
  this.$emit('update:itemSelected', valToEmit); // TODO: deprecated
158
164
  this.$emit('item-clicked', valToEmit);
159
165
  },
160
- onClickTrigger(e) {
161
- this.$nextTick(() => {
162
- if (this.$refs.listbox.clientHeight + e.clientY >= window.innerHeight) {
163
- this.displayTop = true;
164
- }
165
- });
166
-
166
+ onClickTrigger() {
167
167
  this.isOpen = !this.isOpen;
168
-
169
- this.setListBoxPosition();
170
168
  },
171
169
  setListBoxPosition() {
172
- const { top, left, height } = this.$refs.trigger.getBoundingClientRect();
173
- const topValue = Math.floor(top) + Math.floor(height) + window.scrollY;
170
+ const trigger = this.$refs.trigger;
171
+ const listboxHeight = this.$refs.listbox.clientHeight;
172
+
173
+ const { top, left, bottom } = trigger.getBoundingClientRect();
174
+ const topValue = Math.floor(bottom) + window.scrollY;
174
175
  const leftValue = Math.floor(left);
175
176
  this.listboxTop = `${topValue}px`;
176
177
  this.listboxLeft = `${leftValue}px`;
177
- },
178
- teleport(elToMove, elTarget) {
179
- const target = elTarget ?? document.body;
180
178
 
181
- if (target && elToMove) {
182
- target.append(elToMove);
179
+ if (top > listboxHeight && listboxHeight + bottom >= window.innerHeight) {
180
+ this.displayTop = true;
183
181
  }
184
182
  },
185
183
  closeListbox() {
@@ -187,6 +185,11 @@ export default {
187
185
  return;
188
186
  }
189
187
  this.isOpen = false;
188
+ this.isVisible = false;
189
+ },
190
+ onAfterEnter() {
191
+ this.setListBoxPosition();
192
+ this.isVisible = true;
190
193
  },
191
194
  },
192
195
  };