@mozaic-ds/vue 0.20.0 → 0.22.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.
@@ -0,0 +1,251 @@
1
+ <template>
2
+ <div v-click-outside="onClickOutside" class="mc-listbox-options">
3
+ <button
4
+ type="button"
5
+ class="mc-listbox-options__trigger"
6
+ @click="isOpen = !isOpen"
7
+ >
8
+ <m-icon name="DisplayOptions24" />
9
+ <span class="mc-listbox-options__trigger-label">{{ triggerLabel }}</span>
10
+ </button>
11
+ <div
12
+ ref="listbox"
13
+ class="mc-listbox-options__container"
14
+ :class="{ 'is-open': isOpen, 'align-right': position == 'right' }"
15
+ role="listbox"
16
+ aria-labelledby="listbox"
17
+ >
18
+ <ul
19
+ v-for="(list, i) in listItems"
20
+ :key="`list${i}`"
21
+ class="mc-listbox-options__list"
22
+ >
23
+ <li
24
+ v-for="(item, j) in list"
25
+ :key="`item${j}`"
26
+ class="mc-listbox-options__tile"
27
+ :class="{ 'is-disabled': item.disabled }"
28
+ >
29
+ <m-icon
30
+ v-if="item.icon"
31
+ :name="item.icon"
32
+ class="mc-listbox-options__icon"
33
+ :color="item.danger ? '#C61112' : '#71706B'"
34
+ />
35
+ <component
36
+ :is="item.href ? 'a' : 'button'"
37
+ :href="item.href ? item.href : null"
38
+ :type="item.href ? null : 'button'"
39
+ :disabled="item.disabled ? true : null"
40
+ class="mc-listbox-options__item"
41
+ :class="{ 'is-danger': item.danger, 'is-disabled': item.disabled }"
42
+ @click.self="onClickItem(item, i, j)"
43
+ >
44
+ {{ item.text }}
45
+ </component>
46
+ </li>
47
+ </ul>
48
+ </div>
49
+ </div>
50
+ </template>
51
+
52
+ <script>
53
+ import MIcon from '../icon/MIcon.vue';
54
+
55
+ export default {
56
+ name: 'MListBoxActions',
57
+
58
+ components: {
59
+ MIcon,
60
+ },
61
+
62
+ directives: {
63
+ 'click-outside': {
64
+ bind(el, binding, vnode) {
65
+ el.clickOutsideEvent = (event) => {
66
+ if (!(el === event.target || el.contains(event.target))) {
67
+ vnode.context[binding.expression](event);
68
+ }
69
+ };
70
+ document.body.addEventListener('click', el.clickOutsideEvent);
71
+ },
72
+ unbind(el) {
73
+ document.body.removeEventListener('click', el.clickOutsideEvent);
74
+ },
75
+ },
76
+ },
77
+
78
+ props: {
79
+ open: {
80
+ type: Boolean,
81
+ default: false,
82
+ },
83
+ position: {
84
+ type: String,
85
+ default: 'left',
86
+ },
87
+ items: {
88
+ type: Array,
89
+ default: () => [],
90
+ },
91
+ triggerLabel: {
92
+ type: String,
93
+ default: 'Display options',
94
+ },
95
+ },
96
+
97
+ data() {
98
+ return {
99
+ isOpen: this.open,
100
+ };
101
+ },
102
+
103
+ computed: {
104
+ listItems: function () {
105
+ const hasNestedArray = this.items.filter(Array.isArray).length;
106
+
107
+ if (hasNestedArray === 0) {
108
+ const listItems = [];
109
+ listItems.push(this.items);
110
+ return [this.items];
111
+ }
112
+
113
+ return this.items;
114
+ },
115
+ },
116
+
117
+ methods: {
118
+ onClickOutside() {
119
+ this.isOpen = false;
120
+ },
121
+ onClickItem(item, listIndex, itemIndex) {
122
+ const valToEmit = Object.assign(
123
+ { listIndex: listIndex, itemIndex: itemIndex },
124
+ item
125
+ );
126
+ this.$emit('update:itemSelected', valToEmit);
127
+ },
128
+ },
129
+ };
130
+ </script>
131
+
132
+ <style lang="scss">
133
+ @import 'settings-tools/all-settings';
134
+
135
+ .mc-listbox-options {
136
+ display: inline-block;
137
+ position: relative;
138
+
139
+ &__trigger {
140
+ align-items: center;
141
+ background: none;
142
+ border: none;
143
+ cursor: pointer;
144
+ display: flex;
145
+ height: $mu150;
146
+ justify-content: center;
147
+ padding: 0;
148
+ width: $mu150;
149
+
150
+ &-label {
151
+ @include visually-hidden();
152
+ }
153
+ }
154
+
155
+ &__container {
156
+ position: absolute;
157
+ overflow-y: auto;
158
+ opacity: 0;
159
+ visibility: hidden;
160
+ min-width: $mu800;
161
+ background-color: $color-grey-000;
162
+ border: 1px solid $color-grey-600;
163
+ border-radius: 3px;
164
+
165
+ &.is-open {
166
+ opacity: 1;
167
+ visibility: visible;
168
+ z-index: 11;
169
+ }
170
+
171
+ &.align-right {
172
+ transform: translateX(calc(-100% + #{$mu150}));
173
+ }
174
+ }
175
+
176
+ &__list {
177
+ $parent: get-parent-selector(&);
178
+ @include unstyle-list();
179
+ margin: 0 auto;
180
+ padding: 8px 0;
181
+
182
+ &::-webkit-scrollbar {
183
+ background-color: $color-grey-100;
184
+ width: $mu025;
185
+
186
+ &-thumb {
187
+ background: $color-grey-600;
188
+ }
189
+ }
190
+
191
+ &:not(:last-child) {
192
+ border-bottom: 1px solid #bab6bc;
193
+ }
194
+ }
195
+
196
+ &__tile {
197
+ align-items: center;
198
+ color: #1e1e1c;
199
+ display: flex;
200
+ gap: $mu050;
201
+ min-height: $mu250;
202
+ padding-left: $mu075;
203
+ padding-right: $mu075;
204
+ position: relative;
205
+
206
+ &:hover {
207
+ background-color: #eeedea;
208
+ }
209
+
210
+ &.is-disabled {
211
+ background-color: $color-grey-200;
212
+
213
+ &,
214
+ .mc-listbox-options__item {
215
+ color: $color-grey-600;
216
+ cursor: not-allowed;
217
+ pointer-events: none;
218
+ }
219
+ }
220
+ }
221
+
222
+ &__item {
223
+ @include set-font-scale('05', 'm');
224
+
225
+ background: none;
226
+ border: none;
227
+ color: currentColor;
228
+ cursor: pointer;
229
+ padding: 0;
230
+ white-space: nowrap;
231
+
232
+ &::after {
233
+ content: '';
234
+ position: absolute;
235
+ inset: 0;
236
+ z-index: 2;
237
+ }
238
+
239
+ &,
240
+ &:active,
241
+ &:hover,
242
+ &:focus {
243
+ text-decoration: none;
244
+ }
245
+
246
+ &.is-danger {
247
+ color: #c61112;
248
+ }
249
+ }
250
+ }
251
+ </style>
@@ -1,7 +1,12 @@
1
1
  import MListBox from './MListBox.vue';
2
+ import MListBoxActions from './MListBoxActions.vue';
2
3
 
3
4
  MListBox.install = function (Vue) {
4
5
  Vue.component(MListBox.name, MListBox);
5
6
  };
6
7
 
7
- export { MListBox };
8
+ MListBoxActions.install = function (Vue) {
9
+ Vue.component(MListBoxActions.name, MListBoxActions);
10
+ };
11
+
12
+ export { MListBox, MListBoxActions };
@@ -80,6 +80,7 @@
80
80
  @keydown.backspace="
81
81
  (event) => (formatOnBlur ? null : backspaceFunction(event))
82
82
  "
83
+ v-on="$listeners"
83
84
  />
84
85
  </div>
85
86
  </template>
@@ -7,7 +7,7 @@
7
7
  icon-position="left"
8
8
  :aria-label="decrementAriaLabel"
9
9
  :aria-controls="id"
10
- :disabled="currentValue === valuemin"
10
+ :disabled="disabled ? disabled : currentValue === valuemin"
11
11
  :size="small ? 's' : null"
12
12
  tabindex="-1"
13
13
  type="button"
@@ -26,9 +26,11 @@
26
26
  :aria-valuemax="valuemax"
27
27
  :placeholder="placeholder"
28
28
  :size="small ? 's' : null"
29
+ :disabled="disabled"
29
30
  role="spinbutton"
30
31
  @input="handle"
31
32
  @keypress="integerOnly && formatValue($event)"
33
+ v-on="$listeners"
32
34
  />
33
35
 
34
36
  <m-button
@@ -38,7 +40,7 @@
38
40
  icon-position="right"
39
41
  :aria-label="incrementAriaLabel"
40
42
  :aria-controls="id"
41
- :disabled="currentValue === valuemax"
43
+ :disabled="disabled ? disabled : currentValue === valuemax"
42
44
  :size="small ? 's' : null"
43
45
  tabindex="-1"
44
46
  type="button"
@@ -104,6 +106,10 @@ export default {
104
106
  type: Boolean,
105
107
  default: false,
106
108
  },
109
+ disabled: {
110
+ type: Boolean,
111
+ default: false,
112
+ },
107
113
  },
108
114
 
109
115
  data() {
@@ -1,28 +1,58 @@
1
1
  <template>
2
- <nav class='mc-stepper' :class="{ 'mc-stepper--compact': compact, 'mc-stepper--shrinked': steps.length > 3}"
3
- :aria-label='accessibilityLabels.stepperDescription'>
4
- <ol class='mc-stepper__list'>
2
+ <nav
3
+ class="mc-stepper"
4
+ :class="{
5
+ 'mc-stepper--compact': compact,
6
+ 'mc-stepper--shrinked': steps.length > 3,
7
+ }"
8
+ :aria-label="accessibilityLabels.stepperDescription"
9
+ >
10
+ <ol class="mc-stepper__list">
5
11
  <li
6
- v-for='(step, idx) in steps'
7
- :key='`mc-stepper__item-${idx}`'
8
- class='mc-stepper__item'
12
+ v-for="(step, idx) in steps"
13
+ :key="`mc-stepper__item-${idx}`"
14
+ class="mc-stepper__item"
9
15
  :class="{
10
16
  'mc-stepper__item--validated': isStepValidated(idx),
11
17
  'mc-stepper__item--current': step.isCurrent,
12
18
  }"
13
19
  :aria-current="step.isCurrent ? 'step' : false"
14
- :aria-label='stepDescription(step,idx)'
15
- :style='`--steps: ${ steps.length }; --current: ${ idx +1 };`'
20
+ :aria-label="stepDescription(step, idx)"
21
+ :style="`--steps: ${steps.length}; --current: ${idx + 1};`"
16
22
  @click="isStepValidated(idx) && $emit('step-changed', step)"
17
23
  >
18
- <div class='mc-stepper__indicator' aria-hidden='true'>
19
- <m-icon v-if='isStepValidated(idx)' name='NotificationAvailable16' class='mc-stepper__icon' />
20
- <span v-else-if='step.isCurrent'>{{ idx + 1 }}</span>
21
- </div>
22
- <div class='mc-stepper__detail'>
23
- <span class='mc-stepper__title'>{{ idx + 1 }} / {{ steps.length }}</span>
24
- <span class='mc-stepper__label'>{{ step.label }}</span>
25
- </div>
24
+ <a v-if="step.href" :href="step.href" class="mc-stepper__link">
25
+ <div class="mc-stepper__indicator" aria-hidden="true">
26
+ <m-icon
27
+ v-if="isStepValidated(idx)"
28
+ name="NotificationAvailable16"
29
+ class="mc-stepper__icon"
30
+ />
31
+ <span v-else-if="step.isCurrent">{{ idx + 1 }}</span>
32
+ </div>
33
+ <div class="mc-stepper__detail">
34
+ <span class="mc-stepper__title"
35
+ >{{ idx + 1 }} / {{ steps.length }}</span
36
+ >
37
+ <span class="mc-stepper__label">{{ step.label }}</span>
38
+ </div>
39
+ </a>
40
+ <template v-else>
41
+ <div class="mc-stepper__indicator" aria-hidden="true">
42
+ <m-icon
43
+ v-if="isStepValidated(idx)"
44
+ name="NotificationAvailable16"
45
+ class="mc-stepper__icon"
46
+ />
47
+ <span v-else-if="step.isCurrent">{{ idx + 1 }}</span>
48
+ </div>
49
+ <div class="mc-stepper__detail">
50
+ <span class="mc-stepper__title"
51
+ >{{ idx + 1 }} / {{ steps.length }}</span
52
+ >
53
+ <span class="mc-stepper__label">{{ step.label }}</span>
54
+ </div>
55
+ </template>
26
56
  </li>
27
57
  </ol>
28
58
  </nav>
@@ -34,37 +64,48 @@ import MIcon from '../icon/MIcon.vue';
34
64
  export default {
35
65
  name: 'MStepper',
36
66
  components: {
37
- MIcon
67
+ MIcon,
38
68
  },
39
69
  props: {
40
70
  steps: {
41
71
  type: Array,
42
- required: true
72
+ required: true,
43
73
  },
44
74
  compact: {
45
75
  type: Boolean,
46
- default: false
76
+ default: false,
47
77
  },
48
78
  accessibilityLabels: {
49
79
  type: Object,
50
- required: true
51
- }
80
+ required: true,
81
+ },
52
82
  },
53
83
  methods: {
54
84
  isStepValidated(index) {
55
- return index < this.steps.findIndex(step => step.isCurrent);
85
+ return index < this.steps.findIndex((step) => step.isCurrent);
56
86
  },
57
87
  stepDescription(step, index) {
58
- return '#' + (index + 1) + ' ' + step.label + ', ' + this.stepStateLabel(step,index);
88
+ return (
89
+ '#' +
90
+ (index + 1) +
91
+ ' ' +
92
+ step.label +
93
+ ', ' +
94
+ this.stepStateLabel(step, index)
95
+ );
59
96
  },
60
97
  stepStateLabel(step, index) {
61
- return this.isStepValidated(index) ? this.accessibilityLabels.validatedLabel : step.isCurrent ? this.accessibilityLabels.currentLabel : this.accessibilityLabels.disabledLabel;
62
- }
63
- }
98
+ return this.isStepValidated(index)
99
+ ? this.accessibilityLabels.validatedLabel
100
+ : step.isCurrent
101
+ ? this.accessibilityLabels.currentLabel
102
+ : this.accessibilityLabels.disabledLabel;
103
+ },
104
+ },
64
105
  };
65
106
  </script>
66
107
 
67
- <style lang='scss' scoped>
108
+ <style lang="scss" scoped>
68
109
  @import 'settings-tools/_all-settings';
69
110
  @import 'components/_c.stepper';
70
111
  </style>
@@ -6,7 +6,6 @@
6
6
  :class="setClasses"
7
7
  :aria-invalid="isInvalid"
8
8
  :value="value"
9
- @input="$emit('input', $event.target.value)"
10
9
  v-on="inputListeners"
11
10
  />
12
11
  </template>
package/src/index.js CHANGED
@@ -37,7 +37,7 @@ export { MHero } from './components/hero';
37
37
  export { MIcon } from './components/icon';
38
38
  export { MLayer } from './components/layer';
39
39
  export { MLink } from './components/link';
40
- export { MListBox } from './components/listbox';
40
+ export { MListBox, MListBoxActions } from './components/listbox';
41
41
  export { MLoader } from './components/loader';
42
42
  export { MModal } from './components/modal';
43
43
  export { MNotification } from './components/notification';
package/types/index.d.ts CHANGED
@@ -24,6 +24,7 @@ declare module '@mozaic-ds/vue' {
24
24
  const MLayer: VueConstructor;
25
25
  const MLink: VueConstructor;
26
26
  const MListBox: VueConstructor;
27
+ const MListBoxActions: VueConstructor;
27
28
  const MLoader: VueConstructor;
28
29
  const MModal: VueConstructor;
29
30
  const MNotification: VueConstructor;
@@ -71,6 +72,7 @@ declare module '@mozaic-ds/vue' {
71
72
  MLayer,
72
73
  MLink,
73
74
  MListBox,
75
+ MListBoxActions,
74
76
  MLoader,
75
77
  MModal,
76
78
  MNotification,