@dative-gpi/foundation-shared-components 1.0.128 → 1.0.130-maps2

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.
Files changed (55) hide show
  1. package/components/FSBreadcrumbs.vue +20 -12
  2. package/components/FSChip.vue +2 -2
  3. package/components/FSDialogMenu.vue +17 -8
  4. package/components/FSDialogRemove.vue +1 -1
  5. package/components/FSFadeOut.vue +24 -9
  6. package/components/FSIconCard.vue +26 -3
  7. package/components/FSInstantPicker.vue +266 -0
  8. package/components/FSPlayButtons.vue +72 -0
  9. package/components/FSProgressBar.vue +94 -0
  10. package/components/FSSpan.vue +8 -5
  11. package/components/FSText.vue +7 -5
  12. package/components/deviceOrganisations/FSStatusRichCard.vue +170 -0
  13. package/components/fields/FSAutocompleteField.vue +36 -52
  14. package/components/fields/FSDateField.vue +1 -0
  15. package/components/fields/FSSelectField.vue +41 -53
  16. package/components/fields/FSTermField.vue +11 -8
  17. package/components/fields/FSTranslateRichTextField.vue +17 -2
  18. package/components/fields/periodicField/FSPeriodicWeeklyField.vue +21 -11
  19. package/components/lists/FSDataTableUI.vue +30 -19
  20. package/components/map/FSMap.vue +19 -10
  21. package/components/map/FSMapMarker.vue +4 -4
  22. package/components/map/FSMapMarkerClusterGroup.vue +1 -1
  23. package/components/map/FSMapOverlay.vue +34 -19
  24. package/components/tiles/FSGroupTileUI.vue +14 -1
  25. package/components/tiles/FSLocationTileUI.vue +1 -1
  26. package/components/tiles/FSSimpleTileUI.vue +1 -1
  27. package/components/views/desktop/FSBaseDefaultDesktopView.vue +8 -7
  28. package/components/views/desktop/FSBaseEntityDesktopView.vue +1 -0
  29. package/components/views/mobile/FSBaseDefaultMobileView.vue +8 -7
  30. package/components/views/mobile/FSBaseEntityMobileView.vue +1 -0
  31. package/composables/useSlots.ts +2 -1
  32. package/models/rules.ts +5 -2
  33. package/package.json +4 -4
  34. package/styles/components/fs_breadcrumbs.scss +19 -31
  35. package/styles/components/fs_button.scss +7 -5
  36. package/styles/components/fs_chip.scss +8 -6
  37. package/styles/components/fs_clickable.scss +14 -12
  38. package/styles/components/fs_data_iterator_item.scss +12 -10
  39. package/styles/components/fs_dialog.scss +1 -1
  40. package/styles/components/fs_dialog_menu.scss +4 -2
  41. package/styles/components/fs_image_card.scss +5 -3
  42. package/styles/components/fs_map.scss +48 -16
  43. package/styles/components/fs_password_field.scss +4 -2
  44. package/styles/components/fs_progress_bar.scss +14 -0
  45. package/styles/components/fs_select_field.scss +4 -0
  46. package/styles/components/fs_span.scss +12 -4
  47. package/styles/components/fs_status_rich_card.scss +13 -0
  48. package/styles/components/fs_tabs.scss +9 -5
  49. package/styles/components/fs_tag.scss +9 -7
  50. package/styles/components/index.scss +2 -0
  51. package/styles/globals/overrides.scss +11 -4
  52. package/styles/globals/scrollbars.scss +10 -0
  53. package/utils/index.ts +1 -0
  54. package/utils/operations.ts +69 -0
  55. package/components/tiles/FSChartTile.vue +0 -73
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <v-breadcrumbs
3
3
  class="fs-breadcrumbs"
4
- :items="$props.items"
4
+ :items="items"
5
5
  :style="style"
6
6
  v-bind="$attrs"
7
7
  >
@@ -9,7 +9,7 @@
9
9
  #title="{ item }"
10
10
  >
11
11
  <FSSpan
12
- :class="classes(item)"
12
+ class="fs-breadcrumbs-label"
13
13
  >
14
14
  {{ item.title }}
15
15
  </FSSpan>
@@ -31,7 +31,9 @@
31
31
  import { computed, defineComponent, type PropType, type StyleValue } from "vue";
32
32
 
33
33
  import { ColorEnum, type FSBreadcrumbItem } from "@dative-gpi/foundation-shared-components/models";
34
- import { useColors } from "@dative-gpi/foundation-shared-components/composables";
34
+ import { useBreakpoints, useColors } from "@dative-gpi/foundation-shared-components/composables";
35
+
36
+ import { sizeToVar } from "../utils";
35
37
 
36
38
  import FSSpan from "./FSSpan.vue";
37
39
  import FSIcon from "./FSIcon.vue";
@@ -49,28 +51,34 @@ export default defineComponent({
49
51
  default: () => []
50
52
  }
51
53
  },
52
- setup() {
54
+ setup(props) {
55
+ const { isExtraSmall } = useBreakpoints();
53
56
  const { getColors } = useColors();
54
57
 
55
58
  const darks = getColors(ColorEnum.Dark);
56
59
 
57
60
  const style = computed((): StyleValue => ({
61
+ "--fs-breadcrumbs-height" : sizeToVar(["20px", "16px"]),
58
62
  "--fs-breadcrumbs-color" : darks.dark,
59
63
  "--fs-breadcrumbs-active-color" : darks.base,
60
64
  "--fs-breadcrumbs-disabled-color": darks.soft
61
65
  }));
62
66
 
63
- const classes = (item: FSBreadcrumbItem): string[] => {
64
- const classNames = ["fs-breadcrumbs-label"];
65
- if (item.disabled) {
66
- classNames.push("fs-breadcrumbs-label-disabled");
67
+ const items = computed((): FSBreadcrumbItem[] => {
68
+ if (isExtraSmall.value && props.items.length > 3) {
69
+ const mobileItems: FSBreadcrumbItem[] = [0, -2, -1].map((index) => props.items.at(index)!)
70
+ mobileItems.splice(1, 0, {
71
+ title : "...",
72
+ disabled : true
73
+ });
74
+ return mobileItems;
67
75
  }
68
- return classNames;
69
- };
76
+ return props.items;
77
+ });
70
78
 
71
79
  return {
72
- style,
73
- classes
80
+ items,
81
+ style
74
82
  };
75
83
  }
76
84
  });
@@ -103,9 +103,9 @@ export default defineComponent({
103
103
  default: false
104
104
  },
105
105
  align: {
106
- type: String as PropType<"center-left" | "center-center">,
106
+ type: String as PropType<"center-center" | "center-left">,
107
107
  required: false,
108
- default: "center-left"
108
+ default: "center-center"
109
109
  }
110
110
  },
111
111
  setup(props) {
@@ -5,9 +5,8 @@
5
5
  v-bind="$attrs"
6
6
  >
7
7
  <FSCard
8
- width="calc(100vw - 48px)"
9
- padding="8px"
10
- gap="24px"
8
+ :padding="$props.padding"
9
+ :gap="$props.gap"
11
10
  :color="$props.color"
12
11
  :class="classes"
13
12
  >
@@ -38,11 +37,21 @@ export default defineComponent({
38
37
  FSCard
39
38
  },
40
39
  props: {
41
- cardClasses: {
40
+ classes: {
42
41
  type: [Array, String] as PropType<string[] | string | null>,
43
42
  required: false,
44
43
  default: null
45
44
  },
45
+ padding: {
46
+ type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
47
+ required: false,
48
+ default: "8px"
49
+ },
50
+ gap: {
51
+ type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
52
+ required: false,
53
+ default: "24px"
54
+ },
46
55
  modelValue: {
47
56
  type: Boolean,
48
57
  required: false,
@@ -60,12 +69,12 @@ export default defineComponent({
60
69
 
61
70
  const classes = computed((): string[] => {
62
71
  const classNames = ["fs-dialog-menu"];
63
- if (props.cardClasses) {
64
- if (Array.isArray(props.cardClasses)) {
65
- classNames.push(...props.cardClasses);
72
+ if (props.classes) {
73
+ if (Array.isArray(props.classes)) {
74
+ classNames.push(...props.classes);
66
75
  }
67
76
  else {
68
- classNames.push(props.cardClasses);
77
+ classNames.push(props.classes);
69
78
  }
70
79
  }
71
80
  return classNames;
@@ -21,7 +21,7 @@
21
21
  mdi-alert-outline
22
22
  </FSIcon>
23
23
  <FSRow
24
- gap="2px"
24
+ gap="4px"
25
25
  >
26
26
  <FSSpan>
27
27
  {{ $tr("dialog-remove.body-regular", "This action is") }}
@@ -3,7 +3,6 @@
3
3
  class="fs-fade-out"
4
4
  ref="fadeOutRef"
5
5
  :id="elementId"
6
- :style="style"
7
6
  @scroll="$emit('scroll', $event); debounceMasks()"
8
7
  >
9
8
  <slot />
@@ -11,7 +10,7 @@
11
10
  </template>
12
11
 
13
12
  <script lang="ts">
14
- import { computed, defineComponent, onMounted, onUnmounted, type PropType, ref, type StyleValue, watch } from "vue";
13
+ import { computed, defineComponent, onMounted, onUnmounted, type PropType, ref, watch } from "vue";
15
14
 
16
15
  import { useBreakpoints, useColors, useDebounce } from "@dative-gpi/foundation-shared-components/composables";
17
16
  import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
@@ -65,17 +64,21 @@ export default defineComponent({
65
64
  type: Boolean,
66
65
  required: false,
67
66
  default: false
67
+ },
68
+ style:{
69
+ type: Object,
70
+ required: false
68
71
  }
69
72
  },
70
73
  emits: ["scroll"],
71
74
  setup(props) {
72
- const { windowHeight, windowWidth } = useBreakpoints();
75
+ const { windowHeight, windowWidth, isTouchScreenEnabled } = useBreakpoints();
73
76
  const { debounce } = useDebounce();
74
77
  const { getColors } = useColors();
75
78
 
76
79
  const backgrounds = getColors(ColorEnum.Background);
77
80
 
78
- const fadeOutRef = ref(null);
81
+ const fadeOutRef = ref<HTMLElement | null>(null);
79
82
  const bottomMaskHeight = ref("0px");
80
83
  const topMaskHeight = ref("0px");
81
84
  const lastScroll = ref(0);
@@ -84,18 +87,21 @@ export default defineComponent({
84
87
 
85
88
  const elementId = `id${uuidv4()}`;
86
89
 
87
- const style = computed((): StyleValue => ({
90
+ const showOutsideScrollbar = computed(() => props.scrollOutside && !isTouchScreenEnabled.value);
91
+
92
+ const style = computed((): {[index: string]: string} => ({
88
93
  "--fs-fade-out-height" : props.height ? sizeToVar(props.height) : "initial",
89
94
  "--fs-fade-out-max-height" : props.maxHeight ? sizeToVar(props.maxHeight) : "initial",
90
95
  "--fs-fade-out-width" : sizeToVar(props.width),
91
96
  "--fs-fade-out-padding" : sizeToVar(props.padding),
92
- "--fs-fade-out-width-offset" : props.scrollOutside ? '12px' : '0px',
93
- "--fs-fade-out-padding-offset" : props.scrollOutside ? '4px' : '0px',
94
- "--fs-fade-out-margin-right" : props.scrollOutside ? '-12px' : '0px',
97
+ "--fs-fade-out-width-offset" : showOutsideScrollbar.value ? '12px' : '0px',
98
+ "--fs-fade-out-padding-offset" : showOutsideScrollbar.value ? '4px' : '0px',
99
+ "--fs-fade-out-margin-right" : showOutsideScrollbar.value ? '-12px' : '0px',
95
100
  "--fs-fade-out-mask-color" : backgrounds.base,
96
101
  "--fs-fade-out-top-mask-height" : props.disableTopMask ? '0px' : topMaskHeight.value,
97
102
  "--fs-fade-out-bottom-mask-height": props.disableBottomMask ? '0px' : bottomMaskHeight.value,
98
- "--fs-fade-out-x-overflow" : props.hideHorizontalOverflow ? 'hidden' : 'auto'
103
+ "--fs-fade-out-x-overflow" : props.hideHorizontalOverflow ? 'hidden' : 'auto',
104
+ ...props.style
99
105
  }));
100
106
 
101
107
  const handleMasks = () => {
@@ -146,6 +152,15 @@ export default defineComponent({
146
152
 
147
153
  watch([() => windowWidth.value, () => windowHeight.value], debounceMasks);
148
154
 
155
+ watch(() => [style.value, fadeOutRef.value], () => {
156
+ if(!fadeOutRef.value || !style.value) {
157
+ return;
158
+ }
159
+ for(const key in style.value){
160
+ fadeOutRef.value.style.setProperty(key, style.value[key])
161
+ }
162
+ }, { immediate: true})
163
+
149
164
  return {
150
165
  fadeOutRef,
151
166
  elementId,
@@ -11,7 +11,7 @@
11
11
  >
12
12
  <FSIcon
13
13
  :variant="$props.iconVariant"
14
- :color="$props.iconColor"
14
+ :color="contrastedIconColor"
15
15
  :size="actualIconSize"
16
16
  >
17
17
  {{ $props.icon }}
@@ -23,9 +23,10 @@
23
23
  <script lang="ts">
24
24
  import { defineComponent, type PropType, computed } from "vue";
25
25
 
26
- import { type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
26
+ import { ColorEnum, type ColorBase } from "@dative-gpi/foundation-shared-components/models";
27
27
 
28
28
  import { sizeToVar } from "../utils";
29
+ import { useColors } from "../composables";
29
30
 
30
31
  import FSCard from "./FSCard.vue";
31
32
  import FSIcon from "./FSIcon.vue";
@@ -60,7 +61,7 @@ export default defineComponent({
60
61
  iconColor: {
61
62
  type: String as PropType<ColorBase>,
62
63
  required: false,
63
- default: ColorEnum.Dark
64
+ default: ColorEnum.Light
64
65
  },
65
66
  iconVariant: {
66
67
  type: String as PropType<"base" | "baseContrast" | "soft" | "softContrast" | "light" | "lightContrast" | "dark" | "darkContrast">,
@@ -79,6 +80,14 @@ export default defineComponent({
79
80
  }
80
81
  },
81
82
  setup(props){
83
+ const { getColors } = useColors();
84
+
85
+ const colors = computed(() => {
86
+ return Array.isArray(props.backgroundColor)
87
+ ? getColors(props.backgroundColor[Math.floor(props.backgroundColor.length/2)])
88
+ : getColors(props.backgroundColor)
89
+ });
90
+
82
91
  const actualIconSize = computed(() => {
83
92
  if (props.iconSize){
84
93
  return props.iconSize;
@@ -89,7 +98,21 @@ export default defineComponent({
89
98
  return "42px";
90
99
  });
91
100
 
101
+ const contrastedIconColor = computed(() => {
102
+ switch (props.backgroundVariant) {
103
+ case "standard":
104
+ switch (props.iconColor) {
105
+ case ColorEnum.Dark :
106
+ case ColorEnum.Light:
107
+ default: return colors.value.lightContrast!
108
+ };
109
+ case "background": return colors.value.base
110
+ default: return colors.value.baseContrast!
111
+ }
112
+ });
113
+
92
114
  return {
115
+ contrastedIconColor,
93
116
  actualIconSize
94
117
  };
95
118
  }
@@ -0,0 +1,266 @@
1
+ <template>
2
+ <FSBaseField
3
+ :description="$props.description"
4
+ :hideHeader="$props.hideHeader"
5
+ :required="$props.required"
6
+ :editable="$props.editable"
7
+ :label="$props.label"
8
+ >
9
+ <FSRow
10
+ align="bottom-center"
11
+ gap="32px"
12
+ >
13
+ <FSTermField
14
+ width="430px"
15
+ :label="$tr('ui.instant-picker.analyze-period', 'Analyze Period')"
16
+ :startDate="$props.startDate"
17
+ :endDate="$props.endDate"
18
+ @update:startDate="$emit('update:startDate', $event)"
19
+ @update:endDate="$emit('update:endDate', $event)"
20
+ />
21
+ <FSRow
22
+ padding="0 0 2px 0"
23
+ align="center-center"
24
+ >
25
+ <FSCol
26
+ width="fill"
27
+ >
28
+ <FSSlider
29
+ minWidth='min(300px, 90vw)'
30
+ :color="ColorEnum.Light"
31
+ :thumbColor="ColorEnum.Primary"
32
+ :thumbSize="18"
33
+ :trackSize="8"
34
+ thumb-label="always"
35
+ :step="$props.stepTime"
36
+ :min="startTimestamp"
37
+ :max="endTimestamp"
38
+ :ticks="ticks"
39
+ showTicks="always"
40
+ :modelValue="$props.modelValue"
41
+ @update:modelValue="$emit('update:modelValue', $event)"
42
+ >
43
+ <template
44
+ #thumb-label="{ modelValue }"
45
+ >
46
+ <FSSpan
47
+ font="text-overline"
48
+ >
49
+ {{ epochToMonthShortTimeFormat(modelValue) }}
50
+ </FSSpan>
51
+ </template>
52
+ <template
53
+ #tick-label="{ tick, index }"
54
+ >
55
+ <FSRow
56
+ v-if="index % Math.trunc(ticks.length / maximumTickToShow) === 0 || ticks.length < maximumTickToShow"
57
+ >
58
+ <FSText
59
+ :color="lightColors.dark"
60
+ font="text-overline"
61
+ >
62
+ {{ intervalTime <= 3600000
63
+ ?
64
+ epochToShortTimeOnlyFormat(tick.value)
65
+ :
66
+ epochToDayMonthShortOnly(tick.value)
67
+ }}
68
+ </FSText>
69
+ </FSRow>
70
+ </template>
71
+ </FSSlider>
72
+ </FSCol>
73
+ <FSPlayButtons
74
+ v-if="$props.playable"
75
+ :modelValue="playing"
76
+ @click:backward="onClickBackward"
77
+ @click:forward="onClickForward"
78
+ @update:modelValue="onPlayingChange"
79
+ />
80
+ </FSRow>
81
+ </FSRow>
82
+ </FSBaseField>
83
+ </template>
84
+
85
+ <script lang="ts">
86
+ import { computed, defineComponent, ref, watch } from "vue";
87
+
88
+ import { useDateFormat, useTermFieldDate } from "@dative-gpi/foundation-shared-services/composables";
89
+
90
+ import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
91
+ import { useBreakpoints, useColors } from '@dative-gpi/foundation-shared-components/composables';
92
+
93
+ import FSCol from '@dative-gpi/foundation-shared-components/components/FSCol.vue';
94
+ import FSSpan from '@dative-gpi/foundation-shared-components/components/FSSpan.vue';
95
+ import FSText from '@dative-gpi/foundation-shared-components/components/FSText.vue';
96
+ import FSSlider from '@dative-gpi/foundation-shared-components/components/FSSlider.vue';
97
+ import FSBaseField from '@dative-gpi/foundation-shared-components/components/fields/FSBaseField.vue';
98
+ import FSTermField from '@dative-gpi/foundation-shared-components/components/fields/FSTermField.vue';
99
+ import FSPlayButtons from '@dative-gpi/foundation-shared-components/components/FSPlayButtons.vue';
100
+
101
+ export default defineComponent({
102
+ name: "FSInstantPicker",
103
+ components: {
104
+ FSCol,
105
+ FSSpan,
106
+ FSText,
107
+ FSSlider,
108
+ FSTermField,
109
+ FSBaseField,
110
+ FSPlayButtons
111
+ },
112
+ props: {
113
+ label: {
114
+ type: String,
115
+ required: false,
116
+ },
117
+ modelValue: {
118
+ type: Number,
119
+ required: false,
120
+ default: 0,
121
+ },
122
+ startDate: {
123
+ type: String,
124
+ required: true
125
+ },
126
+ endDate: {
127
+ type: String,
128
+ required: true
129
+ },
130
+ description: {
131
+ type: String,
132
+ required: false,
133
+ default: null
134
+ },
135
+ hideHeader: {
136
+ type: Boolean,
137
+ required: false,
138
+ default: false
139
+ },
140
+ required: {
141
+ type: Boolean,
142
+ required: false,
143
+ default: false
144
+ },
145
+ editable: {
146
+ type: Boolean,
147
+ required: false,
148
+ default: true
149
+ },
150
+ playable: {
151
+ type: Boolean,
152
+ required: false,
153
+ default: true
154
+ },
155
+ stepTime: {
156
+ type: Number,
157
+ required: false,
158
+ default: 60000
159
+ },
160
+ playingStepDuration: {
161
+ type: Number,
162
+ required: false,
163
+ default: 50
164
+ }
165
+ },
166
+ emits: ['update:modelValue', 'update:startDate', 'update:endDate'],
167
+ setup(props, { emit }) {
168
+ const { epochToShortTimeOnlyFormat, epochToShortDateFormat, epochToDayMonthShortOnly, epochToISO, epochToMonthShortTimeFormat } = useDateFormat();
169
+ const { convert : convertTermToEpoch } = useTermFieldDate();
170
+ const { isMobileSized, isExtraSmall } = useBreakpoints();
171
+ const { getColors } = useColors();
172
+
173
+ const lightColors = getColors(ColorEnum.Light);
174
+ const playing = ref(false);
175
+ const playingInterval = ref();
176
+
177
+ const startTimestamp = computed(() => convertTermToEpoch(props.startDate));
178
+ const endTimestamp = computed(() => convertTermToEpoch(props.endDate));
179
+
180
+ const intervalTime = computed(() => {
181
+ const possibleIntervals = [60000, 3600000, 86400000];
182
+
183
+ const interval = possibleIntervals.find(interval => {
184
+ return (endTimestamp.value - startTimestamp.value) / interval < 100;
185
+ });
186
+
187
+ if (interval) {
188
+ return interval;
189
+ }
190
+ return 86400000;
191
+ });
192
+
193
+ const ticks = computed(() => {
194
+ const ticks: number[] = [];
195
+
196
+ const firstTick = Math.ceil(startTimestamp.value / intervalTime.value) * intervalTime.value;
197
+ for (let i = firstTick; i <= endTimestamp.value; i += intervalTime.value) {
198
+ ticks.push(i);
199
+ }
200
+ return ticks;
201
+ });
202
+
203
+ const maximumTickToShow = computed(() => {
204
+ if (isMobileSized.value) {
205
+ return 5;
206
+ }
207
+ if (isExtraSmall.value) {
208
+ return 4;
209
+ }
210
+ return 6;
211
+ });
212
+
213
+ const onPlayingChange = (value: boolean) => {
214
+ playing.value = value;
215
+ };
216
+
217
+ const onClickBackward = () => {
218
+ emit('update:modelValue', startTimestamp.value);
219
+ };
220
+
221
+ const onClickForward = () => {
222
+ emit('update:modelValue', endTimestamp.value);
223
+ };
224
+
225
+ watch(() => [props.startDate, props.endDate], () => {
226
+ if(props.modelValue < startTimestamp.value || props.modelValue > endTimestamp.value) {
227
+ emit('update:modelValue', endTimestamp.value);
228
+ }
229
+ }, { immediate: true });
230
+
231
+ watch(playing, (value) => {
232
+ if(!value && playingInterval.value) {
233
+ clearInterval(playingInterval.value);
234
+ } else {
235
+ playingInterval.value = setInterval(() => {
236
+ if(props.modelValue + props.stepTime <= endTimestamp.value) {
237
+ emit('update:modelValue', props.modelValue + props.stepTime);
238
+ } else {
239
+ emit('update:modelValue', endTimestamp.value);
240
+ playing.value = false;
241
+ }
242
+ }, props.playingStepDuration);
243
+ }
244
+ });
245
+
246
+ return {
247
+ ticks,
248
+ playing,
249
+ ColorEnum,
250
+ lightColors,
251
+ intervalTime,
252
+ endTimestamp,
253
+ startTimestamp,
254
+ maximumTickToShow,
255
+ epochToISO,
256
+ onPlayingChange,
257
+ onClickForward,
258
+ onClickBackward,
259
+ epochToShortDateFormat,
260
+ epochToShortTimeOnlyFormat,
261
+ epochToDayMonthShortOnly,
262
+ epochToMonthShortTimeFormat
263
+ };
264
+ },
265
+ });
266
+ </script>
@@ -0,0 +1,72 @@
1
+ <template>
2
+ <FSRow
3
+ width="hug"
4
+ gap="4px"
5
+ >
6
+ <FSClickable
7
+ variant="full"
8
+ :color="ColorEnum.Light"
9
+ borderRadius="50%"
10
+ padding="2px"
11
+ @click="$emit('click:backward')"
12
+ >
13
+ <FSIcon
14
+ size="18px"
15
+ icon="mdi-skip-backward"
16
+ />
17
+ </FSClickable>
18
+ <FSClickable
19
+ variant="full"
20
+ :color="ColorEnum.Light"
21
+ borderRadius="50%"
22
+ padding="2px"
23
+ @click="$emit('update:modelValue', !$props.modelValue)"
24
+ >
25
+ <FSIcon
26
+ size="18px"
27
+ :icon="$props.modelValue ? 'mdi-pause' : 'mdi-play'"
28
+ />
29
+ </FSClickable>
30
+ <FSClickable
31
+ variant="full"
32
+ :color="ColorEnum.Light"
33
+ borderRadius="50%"
34
+ padding="2px"
35
+ @click="$emit('click:forward')"
36
+ >
37
+ <FSIcon
38
+ size="18px"
39
+ icon="mdi-skip-forward"
40
+ />
41
+ </FSClickable>
42
+ </FSRow>
43
+ </template>
44
+
45
+ <script lang="ts">
46
+ import { defineComponent } from "vue";
47
+
48
+ import { ColorEnum } from '@dative-gpi/foundation-shared-components/models';
49
+
50
+ import FSIcon from '@dative-gpi/foundation-shared-components/components/FSIcon.vue';
51
+ import FSClickable from '@dative-gpi/foundation-shared-components/components/FSClickable.vue';
52
+
53
+ export default defineComponent({
54
+ name: "FSPlayButtons",
55
+ components: {
56
+ FSClickable,
57
+ FSIcon
58
+ },
59
+ props: {
60
+ modelValue: {
61
+ type: Boolean,
62
+ required: true,
63
+ }
64
+ },
65
+ emits: ['update:modelValue', 'click:backward', 'click:forward'],
66
+ setup() {
67
+ return {
68
+ ColorEnum
69
+ };
70
+ },
71
+ });
72
+ </script>