@dative-gpi/foundation-shared-components 1.0.194 → 1.1.0-fix01

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 (34) hide show
  1. package/components/FSButton.vue +43 -89
  2. package/components/FSCard.vue +208 -100
  3. package/components/FSCardPlaceholder.vue +29 -25
  4. package/components/FSChip.vue +54 -127
  5. package/components/FSChipGroup.vue +3 -3
  6. package/components/FSClickable.vue +24 -326
  7. package/components/FSColor.vue +3 -3
  8. package/components/FSColorIcon.vue +1 -0
  9. package/components/FSDialogContent.vue +37 -28
  10. package/components/FSEditImageUI.vue +19 -30
  11. package/components/FSIconCheck.vue +8 -0
  12. package/components/FSImageCard.vue +4 -4
  13. package/components/FSLink.vue +1 -13
  14. package/components/FSOptionItem.vue +4 -4
  15. package/components/FSOptionsMenu.vue +6 -6
  16. package/components/FSPlayButtons.vue +8 -8
  17. package/components/FSRouterLink.vue +84 -14
  18. package/components/FSSlideGroup.vue +5 -1
  19. package/components/agenda/FSAgendaHorizontalEvent.vue +4 -4
  20. package/components/agenda/FSAgendaVerticalEvent.vue +4 -4
  21. package/components/deviceOrganisations/FSStatusRichCard.vue +2 -7
  22. package/components/lists/FSFilterButton.vue +11 -8
  23. package/components/lists/FSHeaderButton.vue +6 -3
  24. package/components/tiles/FSTile.vue +31 -65
  25. package/models/index.ts +2 -1
  26. package/models/variants.ts +7 -0
  27. package/package.json +4 -4
  28. package/styles/components/fs_button.scss +1 -7
  29. package/styles/components/fs_card.scss +75 -4
  30. package/styles/components/fs_chip.scss +0 -29
  31. package/styles/components/index.scss +0 -2
  32. package/styles/globals/overrides.scss +1 -1
  33. package/styles/components/fs_clickable.scss +0 -69
  34. package/styles/components/fs_color_icon.scss +0 -3
@@ -1,6 +1,7 @@
1
1
  <template>
2
- <FSClickable
2
+ <FSCard
3
3
  v-if="$props.variant !== 'icon'"
4
+ :clickable="true"
4
5
  :disabled="$props.disabled"
5
6
  :padding="padding"
6
7
  :variant="$props.variant"
@@ -8,7 +9,6 @@
8
9
  :load="$props.load"
9
10
  :href="$props.href"
10
11
  :to="$props.to"
11
- :style="style"
12
12
  @click.stop="onClick"
13
13
  v-bind="$attrs"
14
14
  >
@@ -87,93 +87,62 @@
87
87
  </FSIcon>
88
88
  </slot>
89
89
  </FSCol>
90
- </FSClickable>
91
- <FSRow
90
+ </FSCard>
91
+ <FSRouterLink
92
92
  v-else
93
- width="hug"
93
+ :to="$props.to"
94
+ :href="$props.href"
94
95
  :class="iconClasses"
95
- :style="style"
96
96
  @click.stop="onClick"
97
- v-bind="$attrs"
98
97
  >
99
- <template
100
- v-if="$props.load"
101
- >
102
- <v-progress-circular
103
- class="fs-button-load"
104
- width="2"
105
- size="20"
106
- :indeterminate="true"
107
- :color="loadColor"
108
- />
109
- </template>
110
- <template
111
- v-else-if="$props.href"
98
+ <FSRow
99
+ width="hug"
100
+ align="center-left"
101
+ v-bind="$attrs"
112
102
  >
113
- <a
114
- :href="$props.href"
103
+ <template
104
+ v-if="$props.load"
115
105
  >
116
- <FSIcon
117
- v-if="$props.icon"
118
- :size="$props.iconSize"
119
- >
120
- {{ $props.icon }}
121
- </FSIcon>
122
- <FSSpan
123
- v-if="$props.label"
124
- >
125
- {{ $props.label }}
126
- </FSSpan>
127
- </a>
128
- </template>
129
- <template
130
- v-else-if="$props.to"
131
- >
132
- <FSRouterLink
133
- :to="$props.to"
106
+ <v-progress-circular
107
+ class="fs-button-load"
108
+ width="2"
109
+ size="20"
110
+ :indeterminate="true"
111
+ :color="loadColor"
112
+ />
113
+ </template>
114
+ <template
115
+ v-else
134
116
  >
135
117
  <FSIcon
136
118
  v-if="$props.icon"
119
+ :color="iconVariantColor"
137
120
  :size="$props.iconSize"
138
121
  >
139
122
  {{ $props.icon }}
140
123
  </FSIcon>
141
- <FSSpan
124
+ <FSText
142
125
  v-if="$props.label"
126
+ :color="iconVariantColor"
143
127
  >
144
128
  {{ $props.label }}
145
- </FSSpan>
146
- </FSRouterLink>
147
- </template>
148
- <template
149
- v-else
150
- >
151
- <FSIcon
152
- v-if="$props.icon"
153
- :size="$props.iconSize"
154
- >
155
- {{ $props.icon }}
156
- </FSIcon>
157
- <FSSpan
158
- v-if="$props.label"
159
- >
160
- {{ $props.label }}
161
- </FSSpan>
162
- </template>
163
- </FSRow>
129
+ </FSText>
130
+ </template>
131
+ </FSRow>
132
+ </FSRouterLink>
164
133
  </template>
165
134
 
166
135
  <script lang="ts">
167
- import { computed, defineComponent, type PropType, type StyleValue, useSlots } from "vue";
136
+ import { computed, defineComponent, type PropType, useSlots } from "vue";
168
137
  import { type RouteLocation } from "vue-router";
169
138
 
170
139
  import { type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
171
140
  import { useColors } from "@dative-gpi/foundation-shared-components/composables";
172
141
 
173
- import FSRouterLink from "./FSRouterLink.vue";
174
- import FSClickable from "./FSClickable.vue";
175
- import FSSpan from "./FSSpan.vue";
142
+ import FSRouterLink from './FSRouterLink.vue';
143
+ import FSText from "./FSText.vue";
176
144
  import FSIcon from "./FSIcon.vue";
145
+ import FSCard from './FSCard.vue';
177
146
  import FSCol from "./FSCol.vue";
178
147
  import FSRow from "./FSRow.vue";
179
148
 
@@ -187,8 +156,8 @@ export default defineComponent({
187
156
  name: "FSButton",
188
157
  components: {
189
158
  FSRouterLink,
190
- FSClickable,
191
- FSSpan,
159
+ FSCard,
160
+ FSText,
192
161
  FSIcon,
193
162
  FSCol,
194
163
  FSRow
@@ -265,32 +234,17 @@ export default defineComponent({
265
234
  const { getColors } = useColors();
266
235
 
267
236
  const colors = computed(() => getColors(props.color));
268
- const lights = getColors(ColorEnum.Light);
269
237
  const darks = getColors(ColorEnum.Dark);
270
238
  const slots = useSlots();
271
239
 
272
- const style = computed((): StyleValue => {
240
+ const iconVariantColor = computed((): string => {
273
241
  if (props.disabled) {
274
- switch (props.variant) {
275
- case "icon": return {
276
- "--fs-button-color": lights.dark,
277
- };
278
- }
242
+ return ColorEnum.Light;
279
243
  }
280
- switch (props.variant) {
281
- case "icon": switch (props.color) {
282
- case ColorEnum.Dark:
283
- case ColorEnum.Light: return {
284
- "--fs-button-color" : darks.base,
285
- "--fs-button-hover-color": darks.dark,
286
- };
287
- default: return {
288
- "--fs-button-color" : colors.value.base,
289
- "--fs-button-hover-color": colors.value.dark,
290
- };
291
- }
244
+ if (props.color === ColorEnum.Light) {
245
+ return ColorEnum.Dark;
292
246
  }
293
- return {};
247
+ return props.color;
294
248
  });
295
249
 
296
250
  const iconClasses = computed((): string[] => {
@@ -337,11 +291,11 @@ export default defineComponent({
337
291
  };
338
292
 
339
293
  return {
340
- iconClasses,
341
- loadColor,
342
294
  colors,
343
- style,
344
295
  padding,
296
+ loadColor,
297
+ iconClasses,
298
+ iconVariantColor,
345
299
  onClick
346
300
  };
347
301
  }
@@ -1,142 +1,191 @@
1
1
  <template>
2
- <div
3
- :class="classes"
2
+ <FSRouterLink
4
3
  :style="style"
4
+ :to="$props.to"
5
+ :href="$props.href"
6
+ :type="actualWrapperType"
7
+ :passive="actualClickable ? false : true"
8
+ :class="['fs-card-wrapper', $props.class]"
9
+ v-on="wrapperListeners"
5
10
  >
6
- <slot>
7
- <FSCol
8
- :gap="$props.gap"
9
- >
10
- <FSRow
11
- v-if="$slots.header"
12
- >
13
- <slot
14
- name="header"
15
- />
16
- </FSRow>
17
- <FSRow
18
- v-if="$slots.body"
19
- >
20
- <slot
21
- name="body"
22
- />
23
- </FSRow>
24
- <FSRow
25
- v-if="$slots.footer"
26
- >
27
- <slot
28
- name="footer"
29
- />
30
- </FSRow>
31
- </FSCol>
32
- </slot>
33
- <FSRow
34
- v-if="$slots['top-right']"
35
- class="fs-card-top-right"
11
+ <div
12
+ :class="classes"
36
13
  >
37
14
  <slot
38
- name="top-right"
15
+ name="default"
16
+ v-bind="{ contentVariant }"
17
+ />
18
+ <v-progress-circular
19
+ v-if="$props.load"
20
+ class="fs-card-load__spinner"
21
+ width="2"
22
+ size="24"
23
+ :indeterminate="true"
24
+ :color="loadColor"
39
25
  />
40
- </FSRow>
41
- </div>
26
+ <FSRow
27
+ v-if="$slots['top-right'] && !$props.load"
28
+ class="fs-card-top-right"
29
+ >
30
+ <slot
31
+ name="top-right"
32
+ />
33
+ </FSRow>
34
+ </div>
35
+ </FSRouterLink>
42
36
  </template>
43
37
 
44
38
  <script lang="ts">
45
- import { computed, defineComponent, type PropType, type StyleValue } from "vue";
39
+ import { computed, defineComponent, ref, type PropType, type StyleValue } from "vue";
40
+ import { type RouteLocation } from "vue-router";
46
41
 
47
- import { type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
48
- import { useColors } from "@dative-gpi/foundation-shared-components/composables";
49
42
  import { sizeToVar } from "@dative-gpi/foundation-shared-components/utils";
43
+ import { useColors } from "@dative-gpi/foundation-shared-components/composables";
44
+ import { type CardVariant, type ColorBase, ColorEnum, CardVariants, type ColorBaseVariations } from "@dative-gpi/foundation-shared-components/models";
50
45
 
51
- import FSCol from "./FSCol.vue";
52
46
  import FSRow from "./FSRow.vue";
47
+ import FSRouterLink from "./FSRouterLink.vue";
53
48
 
54
49
  export default defineComponent({
55
50
  name: "FSCard",
56
51
  components: {
57
- FSCol,
52
+ FSRouterLink,
58
53
  FSRow
59
54
  },
60
55
  props: {
61
56
  height: {
62
57
  type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
63
- required: false,
64
58
  default: null
65
59
  },
66
60
  width: {
67
61
  type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
68
- required: false,
69
62
  default: null
70
63
  },
71
64
  maxWidth: {
72
65
  type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
73
- required: false,
74
66
  default: null
75
67
  },
76
68
  padding: {
77
69
  type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
78
- required: false,
79
70
  default: "0"
80
71
  },
81
- gap: {
82
- type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
72
+ class: {
73
+ type: [String, Array] as PropType<string | string[] | null>,
74
+ default: null
75
+ },
76
+ to: {
77
+ type: Object as PropType<RouteLocation | null>,
78
+ default: null
79
+ },
80
+ href: {
81
+ type: String as PropType<string | null>,
82
+ default: null
83
+ },
84
+ onClick: {
85
+ type: Function as PropType<(event: MouseEvent) => void | null>,
83
86
  required: false,
84
- default: "8px"
87
+ default: null
85
88
  },
86
89
  variant: {
87
- type: String as PropType<"background" | "standard" | "full" | "gradient">,
90
+ type: String as PropType<CardVariant>,
88
91
  required: false,
89
- default: "background"
92
+ default: CardVariants.Background
93
+ },
94
+ clickable: {
95
+ type: Boolean as PropType<boolean | null>,
96
+ default: null
90
97
  },
91
98
  color: {
92
99
  type: [Array, String] as PropType<ColorBase | ColorBase[]>,
93
- required: false,
94
100
  default: ColorEnum.Background
95
101
  },
96
102
  border: {
97
103
  type: Boolean,
98
- required: false,
99
104
  default: true
100
105
  },
101
106
  borderRadius: {
102
107
  type: [String, Number],
103
- required: false,
104
108
  default: "4px"
105
109
  },
106
110
  borderStyle: {
107
111
  type: String as PropType<"solid" | "dashed" | "dotted" | "double" | "groove" | "ridge" | "inset" | "outset" | "none">,
108
- required: false,
109
112
  default: "solid"
110
113
  },
111
114
  borderColor: {
112
115
  type: [Array, String] as PropType<ColorBase | null | string>,
113
- required: false,
114
116
  default: null
115
117
  },
116
118
  elevation: {
117
119
  type: Boolean,
118
- required: false,
119
120
  default: false
120
121
  },
121
122
  topRightPadding: {
122
123
  type: [String, Number],
123
- required: false,
124
124
  default: "4px"
125
+ },
126
+ type: {
127
+ type: String as PropType<"button" | "submit" | "reset" | null>,
128
+ default: null
129
+ },
130
+ load: {
131
+ type: Boolean,
132
+ default: false
133
+ },
134
+ disabled: {
135
+ type: Boolean,
136
+ default: false
137
+ },
138
+ disableHoverStyle: {
139
+ type: Boolean,
140
+ default: false
125
141
  }
126
142
  },
127
- setup(props) {
143
+ setup(props, { emit }) {
128
144
  const { getColors, getGradients } = useColors();
129
145
 
146
+ const active = ref(false);
147
+ const hover = ref(false);
148
+
149
+ const backgrounds = getColors(ColorEnum.Background);
150
+ const lights = getColors(ColorEnum.Light);
151
+
130
152
  const colors = computed(() => {
131
153
  if (Array.isArray(props.color)) {
132
154
  return getColors(props.color[0]);
133
155
  }
134
156
  return getColors(props.color);
135
157
  });
158
+
136
159
  const gradients = computed(() => getGradients(props.color, 135));
137
- const backgrounds = getColors(ColorEnum.Background);
138
- const lights = getColors(ColorEnum.Light);
139
- const darks = getColors(ColorEnum.Dark);
160
+
161
+ const actualClickable = computed((): boolean => {
162
+ if (props.clickable === false || props.disabled) {
163
+ return false;
164
+ }
165
+ return props.clickable || !!props.to || !!props.href || !!props.onClick;
166
+ });
167
+
168
+ const actualWrapperType = computed(() => {
169
+ if (props.type) {
170
+ return props.type;
171
+ }
172
+ return "button";
173
+ });
174
+
175
+ const contentVariant = computed((): ColorBaseVariations => {
176
+ if (active.value) {
177
+ return "darkContrast";
178
+ }
179
+ if (hover.value) {
180
+ return "baseContrast";
181
+ }
182
+ switch (props.variant) {
183
+ case "standard" : return "lightContrast";
184
+ case "background": return "base";
185
+ case "full" : return "baseContrast";
186
+ }
187
+ return "base";
188
+ });
140
189
 
141
190
  const borderColor = computed((): ColorBase => {
142
191
  if (props.borderColor) {
@@ -159,59 +208,76 @@ export default defineComponent({
159
208
  }
160
209
  });
161
210
 
211
+ const loadColor = computed((): string => {
212
+ return colors.value[contentVariant.value] ?? colors.value.baseContrast!;
213
+ });
214
+
162
215
  const style = computed((): StyleValue => {
216
+ const baseStyle = {
217
+ "--fs-card-border-size" : props.border ? "1px" : "0",
218
+ "--fs-card-border-style" : props.borderStyle,
219
+ "--fs-card-border-radius" : sizeToVar(props.borderRadius),
220
+ "--fs-card-padding" : sizeToVar(props.padding),
221
+ "--fs-card-height" : sizeToVar(props.height),
222
+ "--fs-card-width" : sizeToVar(props.width),
223
+ "--fs-card-max-width" : sizeToVar(props.maxWidth, "unset"),
224
+ "--fs-card-top-right-padding": sizeToVar(props.topRightPadding)
225
+ };
226
+ if (props.disabled) {
227
+ return {
228
+ ...baseStyle,
229
+ "--fs-card-background-color": lights.light,
230
+ "--fs-card-border-color" : lights.dark,
231
+ "--fs-card-color" : props.clickable ? lights.dark : lights.lightContrast!
232
+ };
233
+ }
234
+
163
235
  switch (props.variant) {
164
236
  case "background": return {
165
- "--fs-card-border-size" : props.border ? "1px" : "0",
166
- "--fs-card-border-style" : props.borderStyle,
167
- "--fs-card-border-radius" : sizeToVar(props.borderRadius),
168
- "--fs-card-padding" : sizeToVar(props.padding),
169
- "--fs-card-height" : sizeToVar(props.height),
170
- "--fs-card-width" : sizeToVar(props.width),
171
- "--fs-card-max-width" : sizeToVar(props.maxWidth, "unset"),
237
+ ...baseStyle,
172
238
  "--fs-card-background-color": backgrounds.base,
173
239
  "--fs-card-border-color" : borderColor.value,
174
- "--fs-card-color" : darks.base,
175
- "--fs-card-top-right-padding": sizeToVar(props.topRightPadding)
240
+ "--fs-card-color" : backgrounds.baseContrast!,
241
+ "--fs-card-hover-background-color" : colors.value.base,
242
+ "--fs-card-hover-border-color" : colors.value.baseContrast!,
243
+ "--fs-card-hover-color" : colors.value.baseContrast!
176
244
  }
177
- case "standard": return {
178
- "--fs-card-border-size" : props.border ? "1px" : "0",
179
- "--fs-card-border-style" : props.borderStyle,
180
- "--fs-card-border-radius" : sizeToVar(props.borderRadius),
181
- "--fs-card-padding" : sizeToVar(props.padding),
182
- "--fs-card-height" : sizeToVar(props.height),
183
- "--fs-card-width" : sizeToVar(props.width),
184
- "--fs-card-max-width" : sizeToVar(props.maxWidth, "unset"),
185
- "--fs-card-background-color": colors.value.light,
186
- "--fs-card-border-color" : borderColor.value,
187
- "--fs-card-color" : colors.value.lightContrast!,
188
- "--fs-card-top-right-padding": sizeToVar(props.topRightPadding)
245
+ case "standard": {
246
+ if (actualClickable.value && !Array.isArray(props.color) && [ColorEnum.Light, ColorEnum.Dark].includes(props.color as ColorEnum)) {
247
+ return {
248
+ ...baseStyle,
249
+ "--fs-card-background-color": backgrounds.base,
250
+ "--fs-card-border-color" : lights.dark,
251
+ "--fs-card-color" : backgrounds.baseContrast!,
252
+ "--fs-card-hover-background-color" : lights.base,
253
+ "--fs-card-hover-border-color" : lights.dark,
254
+ "--fs-card-hover-color" : lights.baseContrast!
255
+ };
256
+ }
257
+ return {
258
+ ...baseStyle,
259
+ "--fs-card-background-color": colors.value.light,
260
+ "--fs-card-border-color" : borderColor.value,
261
+ "--fs-card-color" : colors.value.lightContrast!,
262
+ "--fs-card-hover-background-color" : colors.value.base,
263
+ "--fs-card-hover-border-color" : colors.value.base,
264
+ "--fs-card-hover-color" : colors.value.baseContrast!
265
+ };
189
266
  }
190
267
  case "full": return {
191
- "--fs-card-border-size" : props.border ? "1px" : "0",
192
- "--fs-card-border-style" : props.borderStyle,
193
- "--fs-card-border-radius" : sizeToVar(props.borderRadius),
194
- "--fs-card-padding" : sizeToVar(props.padding),
195
- "--fs-card-height" : sizeToVar(props.height),
196
- "--fs-card-width" : sizeToVar(props.width),
197
- "--fs-card-max-width" : sizeToVar(props.maxWidth, "unset"),
268
+ ...baseStyle,
198
269
  "--fs-card-background-color": colors.value.base,
199
270
  "--fs-card-border-color" : borderColor.value,
200
271
  "--fs-card-color" : colors.value.baseContrast!,
201
- "--fs-card-top-right-padding": sizeToVar(props.topRightPadding)
272
+ "--fs-card-hover-background-color" : colors.value.base,
273
+ "--fs-card-hover-border-color" : colors.value.base,
274
+ "--fs-card-hover-color" : colors.value.baseContrast!
202
275
  }
203
276
  case "gradient": return {
204
- "--fs-card-border-size" : props.border ? "1px" : "0",
205
- "--fs-card-border-style" : props.borderStyle,
206
- "--fs-card-border-radius" : sizeToVar(props.borderRadius),
207
- "--fs-card-padding" : sizeToVar(props.padding),
208
- "--fs-card-height" : sizeToVar(props.height),
209
- "--fs-card-width" : sizeToVar(props.width),
210
- "--fs-card-max-width" : sizeToVar(props.maxWidth, "unset"),
277
+ ...baseStyle,
211
278
  "--fs-card-background-color": gradients.value.base,
212
279
  "--fs-card-border-color" : borderColor.value,
213
- "--fs-card-color" : colors.value.lightContrast!,
214
- "--fs-card-top-right-padding": sizeToVar(props.topRightPadding)
280
+ "--fs-card-color" : colors.value.lightContrast!
215
281
  }
216
282
  }
217
283
  });
@@ -224,21 +290,63 @@ export default defineComponent({
224
290
  break;
225
291
  case "background":
226
292
  classNames.push("fs-card-background");
227
- classNames.push("fs-card-clickable");
228
293
  break;
229
294
  default:
230
295
  classNames.push("fs-card-background");
231
296
  break;
232
297
  }
298
+
299
+ if (actualClickable.value) {
300
+ classNames.push("fs-card-clickable");
301
+ }
302
+ if (props.disableHoverStyle) {
303
+ classNames.push("fs-card-disable-hover-style");
304
+ }
305
+ if (props.disabled) {
306
+ classNames.push("fs-card-disabled");
307
+ }
308
+ if (props.load) {
309
+ classNames.push("fs-card-load");
310
+ }
233
311
  if (props.elevation) {
234
312
  classNames.push("fs-card-elevation");
235
313
  }
314
+
236
315
  return classNames;
237
316
  });
317
+
318
+ const wrapperListeners = computed(() => {
319
+ if (actualClickable.value && !props.disabled) {
320
+ return {
321
+ mouseover: () => { hover.value = true },
322
+ mouseleave: () => { hover.value = false },
323
+ mousedown: () => { active.value = true },
324
+ mouseup: () => { active.value = false },
325
+ "click": onClick
326
+ };
327
+ }
328
+ return {};
329
+ });
330
+
331
+ const onClick = (event: MouseEvent) => {
332
+ if (!actualClickable.value || props.disabled || props.load || props.href || props.to) {
333
+ return;
334
+ }
335
+ emit("click", event);
336
+ };
238
337
 
239
338
  return {
339
+ actualWrapperType,
340
+ actualClickable,
341
+ contentVariant,
342
+ FSRouterLink,
343
+ loadColor,
240
344
  classes,
241
- style
345
+ active,
346
+ hover,
347
+ style,
348
+ onClick,
349
+ wrapperListeners
242
350
  };
243
351
  }
244
352
  });