@mirweb/mir-web-components 2.11.1 → 2.13.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.
@@ -67,6 +67,11 @@ const selectedVariant = computed(() => VARIANTS[props.variant]);
67
67
  &:active:enabled {
68
68
  background-color: $blue-700;
69
69
  }
70
+
71
+ &:focus-visible {
72
+ outline: 2px solid black;
73
+ outline-offset: 2px;
74
+ }
70
75
  }
71
76
 
72
77
  &--next {
@@ -67,6 +67,7 @@ watchEffect(() => {
67
67
  if (!videoRef.value) {
68
68
  return;
69
69
  }
70
+ videoRef.value.muted = props.muted ?? false;
70
71
  if (props.play) {
71
72
  videoRef.value.play();
72
73
  } else if (!props.play) {
@@ -0,0 +1,59 @@
1
+ <template>
2
+ <section class="carousel-video-hero">
3
+ <div class="carousel-video-hero__slides">
4
+ <slot name="carousel-video-hero-slides" />
5
+ </div>
6
+ <div v-if="$slots['carousel-video-hero-controls']" class="carousel-video-hero__controls">
7
+ <slot name="carousel-video-hero-controls" />
8
+ </div>
9
+ </section>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ // Purely slot-based presentational shell — no props, no logic.
14
+ </script>
15
+
16
+ <style lang="scss" scoped>
17
+ @use "../../../assets/scss/variables.scss" as *;
18
+
19
+ .carousel-video-hero {
20
+ position: relative;
21
+ width: 100%;
22
+
23
+ &__slides {
24
+ position: relative;
25
+ width: 100%;
26
+ overflow: hidden;
27
+ min-height: 500px;
28
+
29
+ // Make Splide fill the full slides height
30
+ :deep(.splide),
31
+ :deep(.splide__track),
32
+ :deep(.splide__list),
33
+ :deep(.splide__slide) {
34
+ height: 100%;
35
+ min-height: inherit;
36
+ }
37
+
38
+ // Video fills container
39
+ :deep(.video__wrapper) {
40
+ position: absolute;
41
+ inset: 0;
42
+ }
43
+
44
+ :deep(video) {
45
+ width: 100%;
46
+ height: 100%;
47
+ object-fit: cover;
48
+ }
49
+ }
50
+
51
+ &__controls {
52
+ padding: 16px 30px;
53
+
54
+ @include md {
55
+ padding: 16px max(30px, calc((100% - #{$max-width}) / 2));
56
+ }
57
+ }
58
+ }
59
+ </style>
@@ -25,6 +25,7 @@ export { default as MoleculeTextCard } from "./molecules/text-card/text-card.vue
25
25
  export { default as BlockAccordion } from "./blocks/accordion/accordion.vue";
26
26
  export { default as BlockAuthor } from "./blocks/author/author.vue";
27
27
  export { default as BlockCardDisplay } from "./blocks/card-display/card-display.vue";
28
+ export { default as BlockCarouselVideoHero } from "./blocks/carousel-video-hero/carousel-video-hero.vue";
28
29
  export { default as BlockColumnGrid } from "./blocks/column-grid/column-grid.vue";
29
30
  export { default as BlockFacts } from "./blocks/facts/facts.vue";
30
31
  export { default as BlockFeatures } from "./blocks/features/features.vue";
@@ -1,72 +1,21 @@
1
1
  <template>
2
2
  <div class="footer__wrapper">
3
- <footer class="footer__content">
4
- <img
5
- v-if="language === 'zh'"
6
- src="https://mobile-industrial-robots.com/logo/mir-main-logo.svg"
7
- style="margin: 0 auto"
8
- width="101"
9
- height="45"
10
- />
11
- <div class="footer__sections">
12
- <div
13
- v-for="section in footerSections"
14
- :key="section.title"
15
- class="section"
16
- >
17
- <span class="section__title">{{ section.title }}</span>
18
- <nav :aria-label="'footer navigation ' + section.title">
19
- <ul class="section__list">
20
- <slot name="section-links" :links="section.links"></slot>
21
- </ul>
22
- </nav>
23
- </div>
24
- <div class="section">
25
- <span v-if="language === 'zh'" class="section__title"
26
- >Mobile Industrial Robots</span
27
- >
28
- <span v-else class="section__title"
29
- >Mobile Industrial Robots A/S</span
30
- >
31
- <address>
32
- <span v-if="language === 'zh'"
33
- >上海市普陀区长寿路309弄10号旭辉企业大厦
34
- </span>
35
- <span v-else>Energivej 51</span>
36
- <span v-if="language === 'zh'">19楼1901-1903</span>
37
- <span v-else>5260 Odense S</span>
38
- <span v-if="language !== 'zh'">Denmark</span>
39
- <span v-if="language !== 'zh'">CVR: 29138060</span>
40
- <br />
41
- <atom-link
42
- class="footer__contact"
43
- link-type="regular_light"
44
- underline="false"
45
- ><a
46
- v-if="language === 'zh'"
47
- href="mailto:mir-china@mir-robots.com"
48
- >MiR-China@mir-robots.com</a
49
- ><a v-else href="mailto:mail@mir-robots.com"
50
- >mail@mir-robots.com</a
51
- >
52
- </atom-link>
53
- <atom-link
54
- class="footer__contact"
55
- link-type="regular_light"
56
- underline="false"
57
- ><a v-if="language === 'zh'" href="tel:+862161326299"
58
- >+86 21 6132 6299</a
59
- >
60
- <a v-else href="tel:+4520377577">+45 20 377 577</a>
61
- </atom-link>
62
- </address>
63
- </div>
64
- </div>
65
- <div class="footer__bottom">
66
- <p class="copyright">
3
+ <footer
4
+ class="footer__content"
5
+ :class="{ 'footer__content--simple': isSimpleFooter }"
6
+ >
7
+ <div v-if="isSimpleFooter" class="footer__simple">
8
+ <img
9
+ src="https://mobile-industrial-robots.com/logo/mir-main-logo.svg"
10
+ alt="MiR"
11
+ width="110"
12
+ height="57"
13
+ class="footer__simple-logo"
14
+ />
15
+ <p class="footer__simple-copyright">
67
16
  © Mobile Industrial Robots {{ new Date().getFullYear() }}
68
17
  </p>
69
- <div class="footer__policy">
18
+ <div class="footer__simple-policy">
70
19
  <button
71
20
  v-if="changeRegion"
72
21
  class="footer__language-switcher"
@@ -74,11 +23,10 @@
74
23
  >
75
24
  <span><i class="change-region"></i>{{ changeRegion }}</span>
76
25
  </button>
77
-
78
26
  <slot name="footer-privacy-link"></slot>
79
27
  <slot name="footer-cookie-link"></slot>
80
28
  </div>
81
- <div v-if="language !== 'zh'" class="footer__social">
29
+ <div v-if="language !== 'zh'" class="footer__simple-social">
82
30
  <atom-link
83
31
  v-for="link in socialMedia"
84
32
  :key="link.title"
@@ -95,7 +43,7 @@
95
43
  </a>
96
44
  </atom-link>
97
45
  </div>
98
- <div v-else class="footer__social">
46
+ <div v-else class="footer__simple-social">
99
47
  <atom-link
100
48
  v-for="link in socialMediaChina"
101
49
  :key="link.title"
@@ -113,11 +61,126 @@
113
61
  </atom-link>
114
62
  </div>
115
63
  </div>
64
+ <template v-else>
65
+ <img
66
+ v-if="language === 'zh'"
67
+ src="https://mobile-industrial-robots.com/logo/mir-main-logo.svg"
68
+ style="margin: 0 auto"
69
+ width="101"
70
+ height="45"
71
+ />
72
+ <div class="footer__sections">
73
+ <div
74
+ v-for="section in footerSections"
75
+ :key="section.title"
76
+ class="section"
77
+ >
78
+ <span class="section__title">{{ section.title }}</span>
79
+ <nav :aria-label="'footer navigation ' + section.title">
80
+ <ul class="section__list">
81
+ <slot name="section-links" :links="section.links"></slot>
82
+ </ul>
83
+ </nav>
84
+ </div>
85
+ <div class="section">
86
+ <span v-if="language === 'zh'" class="section__title"
87
+ >Mobile Industrial Robots</span
88
+ >
89
+ <span v-else class="section__title"
90
+ >Mobile Industrial Robots A/S</span
91
+ >
92
+ <address>
93
+ <span v-if="language === 'zh'"
94
+ >上海市普陀区长寿路309弄10号旭辉企业大厦
95
+ </span>
96
+ <span v-else>Energivej 51</span>
97
+ <span v-if="language === 'zh'">19楼1901-1903</span>
98
+ <span v-else>5260 Odense S</span>
99
+ <span v-if="language !== 'zh'">Denmark</span>
100
+ <span v-if="language !== 'zh'">CVR: 29138060</span>
101
+ <br />
102
+ <atom-link
103
+ class="footer__contact"
104
+ link-type="regular_light"
105
+ underline="false"
106
+ ><a
107
+ v-if="language === 'zh'"
108
+ href="mailto:mir-china@mir-robots.com"
109
+ >MiR-China@mir-robots.com</a
110
+ ><a v-else href="mailto:mail@mir-robots.com"
111
+ >mail@mir-robots.com</a
112
+ >
113
+ </atom-link>
114
+ <atom-link
115
+ class="footer__contact"
116
+ link-type="regular_light"
117
+ underline="false"
118
+ ><a v-if="language === 'zh'" href="tel:+862161326299"
119
+ >+86 21 6132 6299</a
120
+ >
121
+ <a v-else href="tel:+4520377577">+45 20 377 577</a>
122
+ </atom-link>
123
+ </address>
124
+ </div>
125
+ </div>
126
+ <div class="footer__bottom">
127
+ <p class="copyright">
128
+ © Mobile Industrial Robots {{ new Date().getFullYear() }}
129
+ </p>
130
+ <div class="footer__policy">
131
+ <button
132
+ v-if="changeRegion"
133
+ class="footer__language-switcher"
134
+ @click="$emit('changeRegionClicked')"
135
+ >
136
+ <span><i class="change-region"></i>{{ changeRegion }}</span>
137
+ </button>
138
+
139
+ <slot name="footer-privacy-link"></slot>
140
+ <slot name="footer-cookie-link"></slot>
141
+ </div>
142
+ <div v-if="language !== 'zh'" class="footer__social">
143
+ <atom-link
144
+ v-for="link in socialMedia"
145
+ :key="link.title"
146
+ underline="false"
147
+ link-type="regular"
148
+ >
149
+ <a :href="link.url" target="_blank" :aria-label="link.title">
150
+ <i
151
+ width="19"
152
+ height="14"
153
+ class="footer__social--icon"
154
+ :class="[link.title ? 'bg-' + link.title : '']"
155
+ ></i>
156
+ </a>
157
+ </atom-link>
158
+ </div>
159
+ <div v-else class="footer__social">
160
+ <atom-link
161
+ v-for="link in socialMediaChina"
162
+ :key="link.title"
163
+ underline="false"
164
+ link-type="regular"
165
+ >
166
+ <a :href="link.url" target="_blank" :aria-label="link.title">
167
+ <i
168
+ width="19"
169
+ height="14"
170
+ class="footer__social--icon"
171
+ :class="[link.title ? 'bg-' + link.title : '']"
172
+ ></i>
173
+ </a>
174
+ </atom-link>
175
+ </div>
176
+ </div>
177
+ </template>
116
178
  </footer>
117
179
  </div>
118
180
  </template>
119
181
 
120
182
  <script setup lang="ts">
183
+ import { computed } from "vue";
121
184
  import AtomLink from "../../atoms/link/link.vue";
122
185
 
123
186
  interface Link {
@@ -136,6 +199,31 @@ interface FooterSection {
136
199
  links: Link[];
137
200
  }
138
201
 
202
+ const props = withDefaults(
203
+ defineProps<{
204
+ language?: string;
205
+ footerSections?: FooterSection[];
206
+ privacyPolicy?: Link;
207
+ cookiePolicy?: Link;
208
+ socialMedia?: Link[];
209
+ socialMediaChina?: Link[];
210
+ changeRegion?: string;
211
+ }>(),
212
+ {
213
+ language: "",
214
+ footerSections: () => [],
215
+ privacyPolicy: undefined,
216
+ cookiePolicy: undefined,
217
+ socialMedia: () => [],
218
+ socialMediaChina: () => [],
219
+ changeRegion: "",
220
+ },
221
+ );
222
+
223
+ const isSimpleFooter = computed(
224
+ () => !props.footerSections || props.footerSections.length === 0,
225
+ );
226
+
139
227
  export type Props = {
140
228
  language?: string;
141
229
  footerSections?: FooterSection[];
@@ -146,16 +234,6 @@ export type Props = {
146
234
  changeRegion?: string;
147
235
  };
148
236
 
149
- withDefaults(defineProps<Props>(), {
150
- language: "",
151
- footerSections: () => [],
152
- privacyPolicy: undefined,
153
- cookiePolicy: undefined,
154
- socialMedia: () => [],
155
- socialMediaChina: () => [],
156
- changeRegion: "",
157
- });
158
-
159
237
  defineEmits(["changeRegionClicked"]);
160
238
  </script>
161
239
 
@@ -182,6 +260,109 @@ defineEmits(["changeRegionClicked"]);
182
260
  @include md {
183
261
  padding: 60px 0px;
184
262
  }
263
+
264
+ &--simple {
265
+ padding: 30px;
266
+
267
+ @include md {
268
+ padding: 60px 0;
269
+ }
270
+ }
271
+ }
272
+
273
+ &__simple {
274
+ display: flex;
275
+ flex-direction: row;
276
+ flex-wrap: wrap;
277
+ align-items: center;
278
+ justify-content: space-between;
279
+ gap: 30px;
280
+ width: 100%;
281
+ }
282
+
283
+ &__simple-logo {
284
+ object-fit: contain;
285
+ }
286
+
287
+ &__simple-copyright {
288
+ font-size: $font-size-xsm;
289
+ margin: 0;
290
+ }
291
+
292
+ &__simple-policy {
293
+ display: flex;
294
+ flex-wrap: wrap;
295
+ flex-direction: row;
296
+ align-items: center;
297
+ gap: 30px;
298
+ color: $blue-600;
299
+
300
+ .footer__language-switcher {
301
+ color: $blue-600;
302
+ cursor: pointer;
303
+ background: none;
304
+ border: none;
305
+ font-size: inherit;
306
+ padding: 0;
307
+ }
308
+ .footer__language-switcher:hover {
309
+ color: #105aa8;
310
+ transition: color 0.3s ease;
311
+ }
312
+
313
+ div div a,
314
+ :slotted(div div a) {
315
+ font-weight: 600;
316
+ }
317
+
318
+ &:hover {
319
+ color: $blue-700;
320
+ transition: color 0.3s ease;
321
+ }
322
+
323
+ .change-region {
324
+ background-image: url("https://a.storyblok.com/f/230581/21x21/23f034f389/world.svg?cv=1695125825717");
325
+ background-position: left center;
326
+ background-size: contain;
327
+ background-repeat: no-repeat;
328
+ padding-left: 30px;
329
+ height: 21px;
330
+ }
331
+ }
332
+
333
+ &__simple-social {
334
+ display: flex;
335
+ flex-direction: row;
336
+ gap: 24px;
337
+ flex-wrap: wrap;
338
+
339
+ .footer__social--icon {
340
+ background: center / contain no-repeat;
341
+ display: block;
342
+ height: 14px;
343
+ width: 19px;
344
+ }
345
+
346
+ .bg {
347
+ &-linkedin {
348
+ background-image: url("https://a.storyblok.com/f/230581/15x14/12341a35e0/linkedin.svg?cv=1695125566502");
349
+ }
350
+ &-facebook {
351
+ background-image: url("https://a.storyblok.com/f/230581/8x14/80c6d8d43f/facebook.svg?cv=1695125566490");
352
+ }
353
+ &-instagram {
354
+ background-image: url("https://a.storyblok.com/f/230581/15x14/234c77d9b1/instagram.svg?cv=1695125566502");
355
+ }
356
+ &-twitter {
357
+ background-image: url("https://a.storyblok.com/f/230581/18x14/8858215cf4/x.svg?cv=1709635053927");
358
+ }
359
+ &-youtube {
360
+ background-image: url("https://a.storyblok.com/f/230581/20x14/9fc8110408/youtube.svg?cv=1695125566462");
361
+ }
362
+ &-wechat {
363
+ background-image: url("https://a.storyblok.com/f/230581/20x14/8eeae45abe/wechat.svg");
364
+ }
365
+ }
185
366
  }
186
367
 
187
368
  &__sections {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mirweb/mir-web-components",
3
3
  "private": false,
4
- "version": "2.11.1",
4
+ "version": "2.13.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"