comand-component-library 3.1.84 → 3.1.87
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/dist/comand-component-library.css +1 -1
- package/dist/comand-component-library.umd.min.js +1 -1
- package/package.json +1 -1
- package/src/App.vue +21 -2
- package/src/assets/data/address-data.json +2 -1
- package/src/assets/data/opening-hours.json +10 -10
- package/src/assets/styles/global-styles.scss +1 -1
- package/src/components/CmdAddressData.vue +37 -29
- package/src/components/CmdFakeSelect.vue +6 -6
- package/src/components/CmdFormElement.vue +35 -25
- package/src/components/CmdListOfRequirements.vue +1 -1
- package/src/components/CmdMainNavigation.vue +8 -7
- package/src/components/CmdOpeningHours.vue +117 -9
- package/src/components/CmdSiteHeader.vue +7 -7
- package/src/components/CmdSlideButton.vue +1 -1
- package/src/components/CmdSwitchLanguage.vue +2 -4
- package/src/components/CmdTable.vue +0 -7
- package/src/components/CmdToggleDarkMode.vue +6 -4
- package/src/components/CmdTooltip.vue +1 -1
- package/src/components/CmdTooltipForInputElements.vue +21 -55
- package/src/documentation/generated/CmdFormElementPropertyDescriptions.json +4 -4
- package/src/documentation/generated/CmdOpeningHoursPropertyDescriptions.json +17 -2
- package/src/documentation/generated/CmdSiteHeaderPropertyDescriptions.json +5 -5
- package/src/documentation/generated/CmdTooltipForInputElementsPropertyDescriptions.json +2 -27
- package/src/mixins/FieldValidation.js +22 -0
package/package.json
CHANGED
package/src/App.vue
CHANGED
@@ -50,6 +50,7 @@
|
|
50
50
|
<li><a href="#section-tabs">Tabs</a></li>
|
51
51
|
<li><a href="#section-thumbnail-scroller">Thumbnail-Scroller</a></li>
|
52
52
|
<li><a href="#section-toggle-darkmode">ToggleDarkMode</a></li>
|
53
|
+
<li><a href="#section-tooltip">Tooltip</a></li>
|
53
54
|
<li><a href="#section-upload-form">Upload-Form</a></li>
|
54
55
|
</ul>
|
55
56
|
</div>
|
@@ -459,10 +460,14 @@
|
|
459
460
|
checkbox with boolean: {{ checkboxValue }}<br/>
|
460
461
|
checkboxes with values: {{ checkboxValues }}
|
461
462
|
</p>
|
463
|
+
|
462
464
|
<h3>Toggle Dark-Mode</h3>
|
463
465
|
<a id="section-toggle-darkmode"></a>
|
466
|
+
<h4>Toggle Dark-Mode (with label, not styled)</h4>
|
464
467
|
<CmdToggleDarkMode :showLabel="true"/>
|
468
|
+
<h4>Toggle Dark-Mode (without label, styled)</h4>
|
465
469
|
<CmdToggleDarkMode :showLabel="false" :use-styled-layout="true" />
|
470
|
+
|
466
471
|
<h2>Checkboxes and Radiobuttons</h2>
|
467
472
|
<h3>Checkboxes [native]</h3>
|
468
473
|
<div class="label inline">
|
@@ -494,6 +499,17 @@
|
|
494
499
|
:status="validationStatus"
|
495
500
|
:disabled="disabledStatus"
|
496
501
|
/>
|
502
|
+
<CmdFormElement element="input"
|
503
|
+
v-model="checkboxValues"
|
504
|
+
inputValue="checkboxValue3"
|
505
|
+
type="checkbox"
|
506
|
+
id="checkbox-with-value-3"
|
507
|
+
:status="validationStatus"
|
508
|
+
:disabled="disabledStatus">
|
509
|
+
<template v-slot:labeltext>
|
510
|
+
Labeltext with <a href="#">link</a> given by slot
|
511
|
+
</template>
|
512
|
+
</CmdFormElement>
|
497
513
|
</div>
|
498
514
|
</div>
|
499
515
|
<h3>Checkboxes (replaced)</h3>
|
@@ -1132,9 +1148,7 @@
|
|
1132
1148
|
:cmdHeadline="{headlineText: 'List of links', headlineLevel: 6}"
|
1133
1149
|
/>
|
1134
1150
|
<CmdOpeningHours :openingHours="openingHoursData"
|
1135
|
-
:closed="true"
|
1136
1151
|
:cmdHeadline="{headlineText: 'Opening hours', headlineLevel: 6}"
|
1137
|
-
textOpenClosed="Closed right now!"
|
1138
1152
|
textHolidaysClosed="Closed on holidays"
|
1139
1153
|
textMiscInfo="Miscellaneous information"
|
1140
1154
|
/>
|
@@ -1243,6 +1257,8 @@ import {openFancyBox} from "@/components/CmdFancyBox"
|
|
1243
1257
|
// import external functions
|
1244
1258
|
import * as functions from "@/mixins/FieldValidation.js"
|
1245
1259
|
|
1260
|
+
import {localizedTime} from "./components/CmdOpeningHours"
|
1261
|
+
|
1246
1262
|
export default {
|
1247
1263
|
name: "App",
|
1248
1264
|
components: {
|
@@ -1417,6 +1433,9 @@ export default {
|
|
1417
1433
|
}
|
1418
1434
|
},
|
1419
1435
|
methods: {
|
1436
|
+
localizedTime(language) {
|
1437
|
+
return (h, m) => (localizedTime(language))(h, m).toLowerCase()
|
1438
|
+
},
|
1420
1439
|
closeCookieDisclaimer(event) {
|
1421
1440
|
this.fancyBoxCookieDisclaimer = false
|
1422
1441
|
alert(event.join(", "))
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"company": {
|
3
|
-
"iconClass": "icon-
|
3
|
+
"iconClass": "icon-company",
|
4
4
|
"value": "Your company name"
|
5
5
|
},
|
6
6
|
"address": {
|
@@ -8,6 +8,7 @@
|
|
8
8
|
"streetNo": "Your Street/No",
|
9
9
|
"zip": "Your zip",
|
10
10
|
"city": "Your city",
|
11
|
+
"miscInfo": "",
|
11
12
|
"country": "Your country",
|
12
13
|
"longitude": "0.0",
|
13
14
|
"latitude": "0.0",
|
@@ -1,29 +1,29 @@
|
|
1
1
|
[
|
2
2
|
{
|
3
3
|
"day": "Mo",
|
4
|
-
"fromTime": "08:
|
5
|
-
"tillTime": "17:
|
4
|
+
"fromTime": "08:00",
|
5
|
+
"tillTime": "17:00"
|
6
6
|
},
|
7
7
|
{
|
8
8
|
"day": "Tu",
|
9
|
-
"fromTime": "08:
|
10
|
-
"tillTime": "17:
|
9
|
+
"fromTime": "08:00",
|
10
|
+
"tillTime": "17:00"
|
11
11
|
},
|
12
12
|
{
|
13
13
|
"day": "We",
|
14
|
-
"fromTime": "08:
|
15
|
-
"tillTime": "17:
|
14
|
+
"fromTime": "08:00",
|
15
|
+
"tillTime": "17:30"
|
16
16
|
},
|
17
17
|
|
18
18
|
{
|
19
19
|
"day": "Th",
|
20
|
-
"fromTime": "08:
|
21
|
-
"tillTime": "17:
|
20
|
+
"fromTime": "08:00",
|
21
|
+
"tillTime": "17:00"
|
22
22
|
},
|
23
23
|
{
|
24
24
|
"day": "Fr",
|
25
|
-
"fromTime": "08:
|
26
|
-
"tillTime": "15:
|
25
|
+
"fromTime": "08:00",
|
26
|
+
"tillTime": "15:00"
|
27
27
|
}
|
28
28
|
]
|
29
29
|
|
@@ -271,7 +271,7 @@ html {
|
|
271
271
|
--color-scheme-background-inverted: var(--light-mode-background-color);
|
272
272
|
--default-background-color-lightness: 20%;
|
273
273
|
|
274
|
-
:where(label, .label) .label-text [class*="icon"] {
|
274
|
+
:where(label, .label) .label-text > [class*="icon"] {
|
275
275
|
background: var(--dark-gray);
|
276
276
|
}
|
277
277
|
}
|
@@ -17,25 +17,28 @@
|
|
17
17
|
<!-- end company -->
|
18
18
|
|
19
19
|
<!-- begin address -->
|
20
|
-
<
|
21
|
-
<
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
<
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
<
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
20
|
+
<template v-if="addressData.address && addressData.address !== undefined">
|
21
|
+
<dt class="address">
|
22
|
+
<span v-if="addressData.address.iconClass && showLabelIcons" :class="addressData.address.iconClass" :title="getMessage('cmdaddressdata.labeltext.address')"></span>
|
23
|
+
<span v-if="showLabelTexts">{{ getMessage('cmdaddressdata.labeltext.address')}}</span>
|
24
|
+
</dt>
|
25
|
+
<dd v-if="addressData.address">
|
26
|
+
<a v-if="linkGoogleMaps" :href="locateAddress" target="google-maps" :title="getMessage('cmdaddressdata.title.open_address_on_google_maps')">
|
27
|
+
<span v-if="addressData.address.streetNo" class="street-address">{{ addressData.address.streetNo }}</span><br/>
|
28
|
+
<span v-if="addressData.address.zip" class="postal-code">{{ addressData.address.zip }} </span>
|
29
|
+
<span v-if="addressData.address.city" class="locality">{{ addressData.address.city }}</span><br/>
|
30
|
+
<span v-if="addressData.address.miscInfo">{{ addressData.address.miscInfo }}</span><br/>
|
31
|
+
<span v-if="addressData.address.country" class="country-name">{{ addressData.address.country }}</span>
|
32
|
+
</a>
|
33
|
+
<template v-else>
|
34
|
+
<span v-if="addressData.address.streetNo" class="street-address">{{addressData.address.streetNo }}</span><br/>
|
35
|
+
<span v-if="addressData.address.zip" class="postal-code">{{ addressData.address.zip }} </span>
|
36
|
+
<span v-if="addressData.address.city" class="locality">{{ addressData.address.city }}</span><br/>
|
37
|
+
<span v-if="addressData.address.miscInfo">{{ addressData.address.miscInfo }}</span><br/>
|
38
|
+
<span v-if="addressData.address.country" class="country-name">{{ addressData.address.country }}</span>
|
39
|
+
</template>
|
40
|
+
</dd>
|
41
|
+
</template>
|
39
42
|
<!-- end address -->
|
40
43
|
|
41
44
|
<!-- begin telephone -->
|
@@ -84,18 +87,19 @@
|
|
84
87
|
<span class="org">{{ addressData.company.value }}</span>
|
85
88
|
</li>
|
86
89
|
<li>
|
87
|
-
<a :href="locateAddress" target="google-maps"
|
88
|
-
|
89
|
-
<span
|
90
|
-
<span
|
91
|
-
<span
|
92
|
-
<span
|
90
|
+
<a v-if="linkGoogleMaps" :href="locateAddress" target="google-maps" :title="getMessage('cmdaddressdata.title.open_address_on_google_maps')">
|
91
|
+
<span v-if="addressData.address.streetNo" class="street-address">{{ addressData.address.streetNo }}</span><br/>
|
92
|
+
<span v-if="addressData.address.zip" class="postal-code">{{ addressData.address.zip }} </span>
|
93
|
+
<span v-if="addressData.address.city" class="locality">{{ addressData.address.city }}</span><br/>
|
94
|
+
<span v-if="addressData.address.miscInfo">{{ addressData.address.miscInfo }}</span><br/>
|
95
|
+
<span v-if="addressData.address.country" class="country-name">{{ addressData.address.country }}</span>
|
93
96
|
</a>
|
94
97
|
<template v-else>
|
95
|
-
<span
|
96
|
-
<span
|
97
|
-
<span
|
98
|
-
<span
|
98
|
+
<span v-if="addressData.address.streetNo" class="street-address">{{ addressData.address.streetNo }}</span><br/>
|
99
|
+
<span v-if="addressData.address.zip" class="postal-code">{{ addressData.address.zip }} </span>
|
100
|
+
<span v-if="addressData.address.city" class="locality">{{ addressData.address.city }}</span><br/>
|
101
|
+
<span v-if="addressData.address.miscInfo">{{ addressData.address.miscInfo }}</span><br/>
|
102
|
+
<span v-if="addressData.address.country" class="country-name">{{ addressData.address.country }}</span>
|
99
103
|
</template>
|
100
104
|
</li>
|
101
105
|
<li v-if="addressData.telephone?.value">
|
@@ -189,6 +193,10 @@ export default {
|
|
189
193
|
dt {
|
190
194
|
display: flex;
|
191
195
|
align-items: center;
|
196
|
+
|
197
|
+
&.address {
|
198
|
+
align-items: flex-start;
|
199
|
+
}
|
192
200
|
}
|
193
201
|
}
|
194
202
|
|
@@ -23,15 +23,11 @@
|
|
23
23
|
<CmdTooltipForInputElements
|
24
24
|
v-if="useCustomTooltip && (validationStatus === '' || validationStatus === 'error')"
|
25
25
|
ref="tooltip"
|
26
|
-
:showRequirements="showRequirements"
|
27
|
-
:inputRequirements="inputRequirements"
|
28
26
|
:validationStatus="validationStatus"
|
29
27
|
:validationMessage="getValidationMessage"
|
30
28
|
:validationTooltip="validationTooltip"
|
31
|
-
:inputAttributes="$attrs"
|
32
|
-
:inputModelValue="modelValue"
|
33
|
-
:helplink="helplink"
|
34
29
|
:relatedId="tooltipId"
|
30
|
+
:cmdListOfRequirements="listOfRequirements"
|
35
31
|
/>
|
36
32
|
<!-- end CmdTooltipForInputElements -->
|
37
33
|
|
@@ -478,6 +474,10 @@ export default {
|
|
478
474
|
margin-left: auto;
|
479
475
|
font-size: 1rem;
|
480
476
|
}
|
477
|
+
|
478
|
+
&:hover, &:active, &:focus {
|
479
|
+
background: var(--primary-color);
|
480
|
+
}
|
481
481
|
}
|
482
482
|
}
|
483
483
|
}
|
@@ -605,7 +605,7 @@ export default {
|
|
605
605
|
}
|
606
606
|
|
607
607
|
&:hover, &:active, &:focus {
|
608
|
-
background: var(--
|
608
|
+
background: var(--color-scheme-background-color);
|
609
609
|
|
610
610
|
span {
|
611
611
|
color: var(--status-color);
|
@@ -22,23 +22,23 @@
|
|
22
22
|
<!-- begin label-text (+ required asterisk) -->
|
23
23
|
<span v-if="(labelText || $slots.labeltext) && $attrs.type !== 'checkbox' && $attrs.type !== 'radio'"
|
24
24
|
:class="['label-text', !showLabel ? 'hidden' : undefined]">
|
25
|
-
<span
|
26
|
-
|
25
|
+
<span>
|
26
|
+
<template v-if="labelText">{{ labelText }}</template>
|
27
|
+
<!-- begin slot 'labeltext' -->
|
28
|
+
<slot v-else name="labeltext" />
|
29
|
+
<!-- end slot 'labeltext' -->
|
30
|
+
<sup v-if="$attrs.required">*</sup>
|
31
|
+
</span>
|
27
32
|
|
28
33
|
<!-- begin CmdTooltipForInputElements -->
|
29
34
|
<CmdTooltipForInputElements
|
30
35
|
v-if="useCustomTooltip && (validationStatus === '' || validationStatus === 'error')"
|
31
36
|
ref="tooltip"
|
32
|
-
:showRequirements="showRequirements"
|
33
|
-
:inputRequirements="inputRequirements"
|
34
37
|
:validationStatus="validationStatus"
|
35
38
|
:validationMessage="getValidationMessage"
|
36
39
|
:validationTooltip="validationTooltip"
|
37
|
-
:inputAttributes="$attrs"
|
38
|
-
:inputModelValue="modelValue"
|
39
|
-
:helplink="helplink"
|
40
40
|
:relatedId="tooltipId"
|
41
|
-
:
|
41
|
+
:cmdListOfRequirements="listOfRequirements"
|
42
42
|
/>
|
43
43
|
<!-- end CmdTooltipForInputElements -->
|
44
44
|
|
@@ -102,18 +102,26 @@
|
|
102
102
|
<!-- begin checkbox and radiobutton -->
|
103
103
|
<template v-else-if="element === 'input' && ($attrs.type === 'checkbox' || $attrs.type === 'radio')">
|
104
104
|
<template v-if="!(onLabel && offLabel)">
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
105
|
+
<input
|
106
|
+
v-bind="elementAttributes"
|
107
|
+
@change="onChange"
|
108
|
+
@blur="onBlur"
|
109
|
+
:checked="isChecked"
|
110
|
+
:value="inputValue"
|
111
|
+
:class="[inputClass, validationStatus, toggleSwitchIconClass, { 'replace-input-type': replaceInputType, 'toggle-switch': toggleSwitch }]"
|
112
|
+
:id="labelId"
|
113
|
+
:disabled="$attrs.disabled"
|
114
|
+
:aria-invalid="validationStatus === 'error'"
|
115
|
+
/>
|
116
|
+
<span v-if="labelText || $slots.labeltext" :class="['label-text', { hidden: !showLabel }]">
|
117
|
+
<span>
|
118
|
+
<template v-if="labelText">{{ labelText }}</template>
|
119
|
+
<!-- begin slot 'labeltext' -->
|
120
|
+
<slot v-else name="labeltext" />
|
121
|
+
<!-- end slot 'labeltext' -->
|
122
|
+
<sup v-if="$attrs.required">*</sup>
|
123
|
+
</span>
|
124
|
+
</span>
|
117
125
|
</template>
|
118
126
|
|
119
127
|
<!-- begin labels for toggle-switch with switch-label -->
|
@@ -479,7 +487,7 @@ export default {
|
|
479
487
|
* icon for error-validated items in list-of-requirements
|
480
488
|
*
|
481
489
|
* element-property must me set to 'input'
|
482
|
-
* showRequirements-
|
490
|
+
* showRequirements-subproperty (of CmdListOfRequirements) must be set to 'true'
|
483
491
|
*
|
484
492
|
*/
|
485
493
|
iconHasStateError: {
|
@@ -496,7 +504,7 @@ export default {
|
|
496
504
|
* icon for warning-validated items in list-of-requirements
|
497
505
|
*
|
498
506
|
* element-property must me set to 'input'
|
499
|
-
* showRequirements-
|
507
|
+
* showRequirements-subproperty (of CmdListOfRequirements) must be set to 'true'
|
500
508
|
*
|
501
509
|
*/
|
502
510
|
iconHasStateWarning: {
|
@@ -513,7 +521,7 @@ export default {
|
|
513
521
|
* icon for success-validated items in list-of-requirements
|
514
522
|
*
|
515
523
|
* element-property must me set to 'input'
|
516
|
-
* showRequirements-
|
524
|
+
* showRequirements-subproperty (of CmdListOfRequirements) must be set to 'true'
|
517
525
|
*
|
518
526
|
*/
|
519
527
|
iconHasStateSuccess: {
|
@@ -530,7 +538,7 @@ export default {
|
|
530
538
|
* icon for info-validated items in list-of-requirements
|
531
539
|
*
|
532
540
|
* element-property must me set to 'input'
|
533
|
-
* showRequirements-
|
541
|
+
* showRequirements-subproperty (of CmdListOfRequirements) must be set to 'true'
|
534
542
|
*
|
535
543
|
*/
|
536
544
|
iconHasStateInfo: {
|
@@ -788,7 +796,9 @@ export default {
|
|
788
796
|
},
|
789
797
|
closeTooltipOnBlur() {
|
790
798
|
// close tooltip by calling function from CmdTooltipForInputElements using $refs
|
791
|
-
this.$refs.tooltip
|
799
|
+
if(this.$refs.tooltip) {
|
800
|
+
this.$refs.tooltip.hideTooltip()
|
801
|
+
}
|
792
802
|
}
|
793
803
|
},
|
794
804
|
watch: {
|
@@ -1,6 +1,5 @@
|
|
1
1
|
<template>
|
2
2
|
<div
|
3
|
-
v-if="navigationEntries.length"
|
4
3
|
:class="[
|
5
4
|
'cmd-main-navigation main-navigation-wrapper',
|
6
5
|
{
|
@@ -20,7 +19,7 @@
|
|
20
19
|
</a>
|
21
20
|
</li>
|
22
21
|
<li v-for="(navigationEntry, index) in navigationEntries" :key="index"
|
23
|
-
:class="{'open' : navigationEntry.open, 'has-subentries': navigationEntry
|
22
|
+
:class="{'active' : navigationEntry.active, 'open' : navigationEntry.open, 'has-subentries': navigationEntry?.subentries?.length}">
|
24
23
|
<!-- begin type === href -->
|
25
24
|
<a
|
26
25
|
v-if="navigationEntry.type === 'href'"
|
@@ -31,7 +30,7 @@
|
|
31
30
|
>
|
32
31
|
<span v-if="navigationEntry.iconClass" :class="navigationEntry.iconClass"></span>
|
33
32
|
<span v-if="navigationEntry.text">{{ navigationEntry.text }}</span>
|
34
|
-
<span v-if="navigationEntry
|
33
|
+
<span v-if="navigationEntry?.subentries?.length"
|
35
34
|
:class="subentriesIconClass"
|
36
35
|
></span>
|
37
36
|
</a>
|
@@ -53,7 +52,7 @@
|
|
53
52
|
<!-- end type === router -->
|
54
53
|
|
55
54
|
<!-- begin sub-level 1 -->
|
56
|
-
<ul v-if="navigationEntry
|
55
|
+
<ul v-if="navigationEntry?.subentries?.length" aria-expanded="true">
|
57
56
|
<li v-for="(navigationSubEntry, subindex) in navigationEntry.subentries" :key="subindex"
|
58
57
|
:class="{'open' : navigationSubEntry.open}">
|
59
58
|
<!-- begin type === href -->
|
@@ -227,14 +226,16 @@ export default {
|
|
227
226
|
methods: {
|
228
227
|
executeLink(event, navigationEntry) {
|
229
228
|
if (navigationEntry.target || (navigationEntry.path.length > 1)) {
|
229
|
+
this.showOffcanvas = false
|
230
230
|
return true
|
231
231
|
}
|
232
232
|
if (navigationEntry.path === '#' || navigationEntry.path === '') {
|
233
233
|
event.preventDefault()
|
234
|
+
this.showOffcanvas = false
|
234
235
|
this.$emit('click', navigationEntry.path)
|
235
236
|
|
236
237
|
}
|
237
|
-
if (!(navigationEntry
|
238
|
+
if (!(navigationEntry?.subentries?.length)) {
|
238
239
|
this.showOffcanvas = false
|
239
240
|
} else {
|
240
241
|
// add entry "open" to navigationEntry-object (will be watched by vue3 automatically)
|
@@ -439,7 +440,7 @@ export default {
|
|
439
440
|
> a {
|
440
441
|
span {
|
441
442
|
+ span[class*="icon"]::before {
|
442
|
-
|
443
|
+
|
443
444
|
}
|
444
445
|
}
|
445
446
|
}
|
@@ -448,7 +449,7 @@ export default {
|
|
448
449
|
> a {
|
449
450
|
span {
|
450
451
|
+ span[class*="icon"]::before {
|
451
|
-
|
452
|
+
|
452
453
|
}
|
453
454
|
}
|
454
455
|
}
|
@@ -6,21 +6,21 @@
|
|
6
6
|
|
7
7
|
<!-- begin opening-status with link to detail-page -->
|
8
8
|
<template v-if="link && link?.path && link?.show">
|
9
|
-
<a v-if="link.type === 'href'" :href="link.path" :class="{closed:
|
10
|
-
<router-link v-if="link.type === 'router'" :to="link.path" :class="{closed:
|
11
|
-
<button v-if="link.type === 'button'" :class="['button', {closed:
|
9
|
+
<a v-if="link.type === 'href'" :href="link.path" :class="{closed: isClosed}">{{ textOpenClosed }}</a>
|
10
|
+
<router-link v-if="link.type === 'router'" :to="link.path" :class="{closed: isClosed}">{{ textOpenClosed }}</router-link>
|
11
|
+
<button v-if="link.type === 'button'" :class="['button', {closed: isClosed}]">{{ textOpenClosed }}</button>
|
12
12
|
</template>
|
13
13
|
<!-- end opening-status with link to detail-page -->
|
14
14
|
|
15
15
|
<!-- begin opening-status (without link) -->
|
16
|
-
<span v-else :class="{'closed':
|
16
|
+
<span v-else :class="{'closed': isClosed}">{{ textOpenClosed }}</span>
|
17
17
|
<!-- end opening-status (without link) -->
|
18
18
|
|
19
19
|
<!-- begin opening-days and -hours -->
|
20
20
|
<dl>
|
21
|
-
<template v-for="day in
|
21
|
+
<template v-for="day in openingHoursFormatted" :key="day.day">
|
22
22
|
<dt>{{ day.day }}:</dt>
|
23
|
-
<dd>{{ day.fromTime
|
23
|
+
<dd>{{ getTime(day.fromTime)}}–{{ getTime(day.tillTime)}}</dd>
|
24
24
|
</template>
|
25
25
|
</dl>
|
26
26
|
<!-- end opening-days and -hours -->
|
@@ -40,6 +40,36 @@
|
|
40
40
|
// import components
|
41
41
|
import CmdHeadline from "./CmdHeadline"
|
42
42
|
|
43
|
+
export function localizedTime(language) {
|
44
|
+
return (hour, minute) => {
|
45
|
+
const now = new Date()
|
46
|
+
now.setHours(hour, minute, 0, 0)
|
47
|
+
return new Intl.DateTimeFormat(language, {timeStyle: "short"}).format(now)
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
export function timeFormatting(separator, suffix1, suffix2, hoursLeadingZero = true) {
|
52
|
+
function addLeadingZero(time, addLeadingZero) {
|
53
|
+
if(addLeadingZero && time < 10) {
|
54
|
+
return "0" + time
|
55
|
+
}
|
56
|
+
return time
|
57
|
+
}
|
58
|
+
|
59
|
+
return (hour, minute) => {
|
60
|
+
if(suffix2) {
|
61
|
+
let hour12 = hour
|
62
|
+
let currentSuffix = suffix1
|
63
|
+
if(hour12 > 12) {
|
64
|
+
hour12 -= 12
|
65
|
+
currentSuffix = suffix2
|
66
|
+
}
|
67
|
+
return addLeadingZero(hour12, hoursLeadingZero) + separator + addLeadingZero(minute, true) + currentSuffix
|
68
|
+
}
|
69
|
+
return addLeadingZero(hour, hoursLeadingZero) + separator + addLeadingZero(minute, true) + suffix1
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
43
73
|
export default {
|
44
74
|
name: "CmdOpeningHours",
|
45
75
|
components: {
|
@@ -63,11 +93,18 @@ export default {
|
|
63
93
|
default: false
|
64
94
|
},
|
65
95
|
/**
|
66
|
-
* text for open
|
96
|
+
* text for 'open'-information
|
67
97
|
*/
|
68
|
-
|
98
|
+
textOpen: {
|
69
99
|
type: String,
|
70
|
-
|
100
|
+
default: "Open right now!"
|
101
|
+
},
|
102
|
+
/**
|
103
|
+
* text for 'closed'-information
|
104
|
+
*/
|
105
|
+
textClosed: {
|
106
|
+
type: String,
|
107
|
+
default: "Closed right now!"
|
71
108
|
},
|
72
109
|
/**
|
73
110
|
* list of opening-hours
|
@@ -96,6 +133,77 @@ export default {
|
|
96
133
|
cmdHeadline: {
|
97
134
|
type: Object,
|
98
135
|
required: false
|
136
|
+
},
|
137
|
+
timeFormatter: {
|
138
|
+
type: Function,
|
139
|
+
required: false
|
140
|
+
},
|
141
|
+
componentHandlesClosedStatus: {
|
142
|
+
type: Boolean,
|
143
|
+
default: true
|
144
|
+
}
|
145
|
+
},
|
146
|
+
computed: {
|
147
|
+
textOpenClosed() {
|
148
|
+
return this.isClosed ? this.textClosed : this.textOpen
|
149
|
+
},
|
150
|
+
openingHoursFormatted() {
|
151
|
+
const weekdays = []
|
152
|
+
for(let i = 0; i < this.openingHours.length; i++) {
|
153
|
+
const openingHours = {}
|
154
|
+
const splitFromTime = this.openingHours[i].fromTime.split(/[:.]/)
|
155
|
+
const splitTillTime = this.openingHours[i].tillTime.split(/[:.]/)
|
156
|
+
|
157
|
+
openingHours.day = this.openingHours[i].day
|
158
|
+
openingHours.fromTime = {
|
159
|
+
hours: parseInt(splitFromTime[0]),
|
160
|
+
mins: parseInt(splitFromTime[1])
|
161
|
+
}
|
162
|
+
openingHours.tillTime = {
|
163
|
+
hours: parseInt(splitTillTime[0]),
|
164
|
+
mins: parseInt(splitTillTime[1])
|
165
|
+
}
|
166
|
+
weekdays.push(openingHours)
|
167
|
+
}
|
168
|
+
return weekdays
|
169
|
+
},
|
170
|
+
isClosed() {
|
171
|
+
if(!this.componentHandlesClosedStatus) {
|
172
|
+
return this.closed
|
173
|
+
}
|
174
|
+
|
175
|
+
const currentDate = new Date()
|
176
|
+
let currentDay = currentDate.getDay()
|
177
|
+
|
178
|
+
// fix order and check if currentDay equals 0 === sunday. Data are expected to start with monday
|
179
|
+
if (currentDay === 0){
|
180
|
+
currentDay = 6
|
181
|
+
} else {
|
182
|
+
currentDay -= 1
|
183
|
+
}
|
184
|
+
|
185
|
+
const openingHours = this.openingHoursFormatted[currentDay]
|
186
|
+
|
187
|
+
if(this.openingHoursFormatted[currentDay]) {
|
188
|
+
const openingHoursFrom = new Date()
|
189
|
+
openingHoursFrom.setHours(openingHours.fromTime.hours, openingHours.fromTime.mins)
|
190
|
+
|
191
|
+
const openingHoursTill = new Date()
|
192
|
+
openingHoursTill.setHours(openingHours.tillTime.hours, openingHours.tillTime.mins)
|
193
|
+
|
194
|
+
if (openingHoursFrom <= currentDate && currentDate <= openingHoursTill) {
|
195
|
+
return false
|
196
|
+
}
|
197
|
+
}
|
198
|
+
return true
|
199
|
+
}
|
200
|
+
},
|
201
|
+
methods: {
|
202
|
+
getTime(time) {
|
203
|
+
if(this.timeFormatter) {
|
204
|
+
return this.timeFormatter(time.hours, time.mins)
|
205
|
+
}
|
206
|
+
return timeFormatting(":", " hrs", "", false)(time.hours, time.mins)
|
99
207
|
}
|
100
208
|
}
|
101
209
|
}
|