@dative-gpi/foundation-shared-components 0.0.37 → 0.0.39

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,311 @@
1
+ <template>
2
+ <FSWrapGroup
3
+ v-if="['wrap'].includes($props.variant)"
4
+ class="fs-option-group"
5
+ :padding="$props.padding"
6
+ :gap="$props.gap"
7
+ :style="style"
8
+ >
9
+ <template v-if="$props.values.length">
10
+ <template v-if="!firstChild">
11
+ <FSOptionItem
12
+ v-for="(item, index) in $props.values"
13
+ :prependIcon="item.prependIcon"
14
+ :appendIcon="item.appendIcon"
15
+ :editable="$props.editable"
16
+ :variant="getVariant(item)"
17
+ :color="getColor(item)"
18
+ :class="getClass(item)"
19
+ :label="item.label"
20
+ :icon="item.icon"
21
+ :key="index"
22
+ @click="toggle(item)"
23
+ />
24
+ </template>
25
+ <template v-else>
26
+ <component
27
+ v-for="(item, index) in $props.values"
28
+ :key="index"
29
+ :is="firstChild"
30
+ :prependIcon="getFromFirstChild('prependIcon', item)"
31
+ :appendIcon="getFromFirstChild('appendIcon', item)"
32
+ :variant="getFromFirstChild('variant', item)"
33
+ :color="getFromFirstChild('color', item)"
34
+ :class="getFromFirstChild('class', item)"
35
+ :label="getFromFirstChild('label', item)"
36
+ :icon="getFromFirstChild('icon', item)"
37
+ :editable="$props.editable"
38
+ @click="toggle(item)"
39
+ />
40
+ </template>
41
+ </template>
42
+ <slot v-else />
43
+ </FSWrapGroup>
44
+ <FSSlideGroup
45
+ v-else
46
+ class="fs-option-group"
47
+ :padding="$props.padding"
48
+ :gap="$props.gap"
49
+ :style="style"
50
+ >
51
+ <template v-if="$props.values.length">
52
+ <template v-if="!firstChild">
53
+ <FSOptionItem
54
+ v-for="(item, index) in $props.values"
55
+ :prependIcon="item.prependIcon"
56
+ :appendIcon="item.appendIcon"
57
+ :editable="$props.editable"
58
+ :variant="getVariant(item)"
59
+ :color="getColor(item)"
60
+ :class="getClass(item)"
61
+ :label="item.label"
62
+ :icon="item.icon"
63
+ :key="index"
64
+ @click="toggle(item)"
65
+ />
66
+ </template>
67
+ <template v-else>
68
+ <component
69
+ v-for="(item, index) in $props.values"
70
+ :key="index"
71
+ :is="firstChild"
72
+ :prependIcon="getFromFirstChild('prependIcon', item)"
73
+ :appendIcon="getFromFirstChild('appendIcon', item)"
74
+ :variant="getFromFirstChild('variant', item)"
75
+ :color="getFromFirstChild('color', item)"
76
+ :class="getFromFirstChild('class', item)"
77
+ :label="getFromFirstChild('label', item)"
78
+ :icon="getFromFirstChild('icon', item)"
79
+ :editable="$props.editable"
80
+ @click="toggle(item)"
81
+ />
82
+ </template>
83
+ </template>
84
+ <slot v-else />
85
+ </FSSlideGroup>
86
+ </template>
87
+
88
+ <script lang="ts">
89
+ import { computed, defineComponent, PropType } from "vue";
90
+
91
+ import { useColors, useSlots } from "@dative-gpi/foundation-shared-components/composables";
92
+ import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
93
+ import { sizeToVar } from "@dative-gpi/foundation-shared-components/utils";
94
+ import { FSToggle } from "@dative-gpi/foundation-shared-components/models";
95
+
96
+ import FSOptionItem from "./FSOptionItem.vue";
97
+ import FSSlideGroup from "./FSSlideGroup.vue";
98
+ import FSWrapGroup from "./FSWrapGroup.vue";
99
+
100
+ export default defineComponent({
101
+ name: "FSOptionGroup",
102
+ components: {
103
+ FSOptionItem,
104
+ FSSlideGroup,
105
+ FSWrapGroup
106
+ },
107
+ props: {
108
+ values: {
109
+ type: Array as PropType<FSToggle[]>,
110
+ required: false,
111
+ default: () => []
112
+ },
113
+ border: {
114
+ type: Boolean,
115
+ required: false,
116
+ default: true
117
+ },
118
+ borderRadius: {
119
+ type: [String, Number],
120
+ required: false,
121
+ default: "4px"
122
+ },
123
+ variant: {
124
+ type: String as PropType<"wrap" | "slide">,
125
+ required: false,
126
+ default: "wrap"
127
+ },
128
+ optionVariant: {
129
+ type: String as PropType<"standard" | "full">,
130
+ required: false,
131
+ default: "full"
132
+ },
133
+ activeVariant: {
134
+ type: String as PropType<"standard" | "full">,
135
+ required: false,
136
+ default: "full"
137
+ },
138
+ optionClass: {
139
+ type: [Array, String] as PropType<string[] | string>,
140
+ required: false,
141
+ default: null
142
+ },
143
+ activeClass: {
144
+ type: [Array, String] as PropType<string[] | string>,
145
+ required: false,
146
+ default: null
147
+ },
148
+ modelValue: {
149
+ type: [Array, String, Number] as PropType<(string | number)[] | string | number>,
150
+ required: false,
151
+ default: false
152
+ },
153
+ optionColor: {
154
+ type: String as PropType<ColorBase>,
155
+ required: false,
156
+ default: ColorEnum.Background
157
+ },
158
+ activeColor: {
159
+ type: String as PropType<ColorBase>,
160
+ required: false,
161
+ default: ColorEnum.Primary
162
+ },
163
+ padding: {
164
+ type: [String, Number],
165
+ required: false,
166
+ default: "3px"
167
+ },
168
+ gap: {
169
+ type: [String, Number],
170
+ required: false,
171
+ default: "0"
172
+ },
173
+ multiple: {
174
+ type: Boolean,
175
+ required: false,
176
+ default: false
177
+ },
178
+ required: {
179
+ type: Boolean,
180
+ required: false,
181
+ default: true
182
+ },
183
+ editable: {
184
+ type: Boolean,
185
+ required: false,
186
+ default: true
187
+ }
188
+ },
189
+ emits: ["update:modelValue"],
190
+ setup(props, { emit }) {
191
+ const { getFirstChild } = useSlots();
192
+ const { getColors } = useColors();
193
+
194
+ const lights = getColors(ColorEnum.Light);
195
+
196
+ const firstChild = getFirstChild("item");
197
+
198
+ const style = computed((): { [code: string]: string } & Partial<CSSStyleDeclaration> => {
199
+ return {
200
+ "--fs-option-group-border-size" : props.border ? "1px" : "0",
201
+ "--fs-option-group-border-radius": sizeToVar(props.borderRadius),
202
+ "--fs-option-group-border-color" : lights.base
203
+ };
204
+ })
205
+
206
+ const getFromFirstChild = (prop: string, value: FSToggle): any => {
207
+ switch (prop) {
208
+ case "prependIcon":
209
+ return firstChild.props.prependIcon ?? value.prependIcon;
210
+ case "label":
211
+ return firstChild.props.label ?? value.label;
212
+ case "appendIcon":
213
+ return firstChild.props.appendIcon ?? value.appendIcon;
214
+ case "icon":
215
+ return firstChild.props.icon ?? value.icon;
216
+ case "variant":
217
+ return firstChild.props.variant ?? getVariant(value);
218
+ case "color":
219
+ return firstChild.props.color ?? getColor(value);
220
+ default:
221
+ return firstChild.props[prop];
222
+ }
223
+ }
224
+
225
+ const getVariant = (value: FSToggle): "standard" | "full" => {
226
+ if (Array.isArray(props.modelValue) && props.modelValue.some(v => v === value.id)) {
227
+ return props.activeVariant;
228
+ }
229
+ if (!Array.isArray(props.modelValue) && props.modelValue === value.id) {
230
+ return props.activeVariant;
231
+ }
232
+ return props.optionVariant;
233
+ };
234
+
235
+ const getColor = (value: FSToggle): ColorBase => {
236
+ if (Array.isArray(props.modelValue) && props.modelValue.some(v => v === value.id)) {
237
+ return props.activeColor;
238
+ }
239
+ if (!Array.isArray(props.modelValue) && props.modelValue === value.id) {
240
+ return props.activeColor;
241
+ }
242
+ return props.optionColor;
243
+ };
244
+
245
+ const getClass = (value: FSToggle): string[] | string => {
246
+ if (Array.isArray(props.modelValue) && props.modelValue.some(v => v === value.id)) {
247
+ return props.activeClass;
248
+ }
249
+ if (!Array.isArray(props.modelValue) && props.modelValue === value.id) {
250
+ return props.activeClass;
251
+ }
252
+ return props.optionClass;
253
+ };
254
+
255
+ const toggle = (value: FSToggle): void => {
256
+ if (Array.isArray(props.modelValue)) {
257
+ if (props.multiple) {
258
+ if (props.modelValue.length && props.modelValue.every(v => v === value.id)) {
259
+ if (!props.required) {
260
+ emit("update:modelValue", []);
261
+ return;
262
+ }
263
+ }
264
+ else if (props.modelValue.some(v => v === value.id)) {
265
+ emit("update:modelValue", props.modelValue.filter(v => v !== value.id));
266
+ return;
267
+ }
268
+ else {
269
+ emit("update:modelValue", [...props.modelValue, value.id]);
270
+ return;
271
+ }
272
+ }
273
+ else {
274
+ if (props.modelValue.some(v => v === value.id)) {
275
+ if (!props.required) {
276
+ emit("update:modelValue", []);
277
+ return;
278
+ }
279
+ }
280
+ else {
281
+ emit("update:modelValue", [value.id]);
282
+ return;
283
+ }
284
+ }
285
+ }
286
+ else {
287
+ if (props.modelValue === value.id) {
288
+ if (!props.required) {
289
+ emit("update:modelValue", null);
290
+ return;
291
+ }
292
+ }
293
+ else {
294
+ emit("update:modelValue", value.id);
295
+ return;
296
+ }
297
+ }
298
+ };
299
+
300
+ return {
301
+ firstChild,
302
+ style,
303
+ getFromFirstChild,
304
+ getVariant,
305
+ getColor,
306
+ getClass,
307
+ toggle
308
+ };
309
+ }
310
+ })
311
+ </script>
@@ -0,0 +1,132 @@
1
+ <template>
2
+ <FSClickable
3
+ padding="12px 0"
4
+ :editable="$props.editable"
5
+ :height="['32px', '28px']"
6
+ :variant="$props.variant"
7
+ :color="$props.color"
8
+ :load="$props.load"
9
+ :width="width"
10
+ @click.stop="onClick"
11
+ v-bind="$attrs"
12
+ >
13
+ <FSRow
14
+ align="center-center"
15
+ width="fill"
16
+ :wrap="false"
17
+ >
18
+ <slot name="prepend" v-bind="{ color: $props.color, colors }">
19
+ <FSIcon
20
+ v-if="$props.prependIcon || $props.icon"
21
+ size="l"
22
+ >
23
+ {{ $props.prependIcon ?? $props.icon }}
24
+ </FSIcon>
25
+ </slot>
26
+ <slot v-bind="{ color: $props.color, colors }">
27
+ <FSSpan
28
+ v-if="$props.label"
29
+ >
30
+ {{ $props.label }}
31
+ </FSSpan>
32
+ </slot>
33
+ <slot name="append" v-bind="{ color: $props.color, colors }">
34
+ <FSIcon
35
+ v-if="$props.appendIcon"
36
+ size="l"
37
+ >
38
+ {{ $props.appendIcon }}
39
+ </FSIcon>
40
+ </slot>
41
+ </FSRow>
42
+ </FSClickable>
43
+ </template>
44
+
45
+ <script lang="ts">
46
+ import { computed, defineComponent, PropType } from "vue";
47
+
48
+ import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
49
+ import { useColors } from "@dative-gpi/foundation-shared-components/composables";
50
+
51
+ import FSClickable from "./FSClickable.vue";
52
+ import FSSpan from "./FSSpan.vue";
53
+ import FSIcon from "./FSIcon.vue";
54
+ import FSRow from "./FSRow.vue";
55
+
56
+ export default defineComponent({
57
+ name: "FSOptionItem",
58
+ components: {
59
+ FSClickable,
60
+ FSSpan,
61
+ FSIcon,
62
+ FSRow
63
+ },
64
+ props: {
65
+ prependIcon: {
66
+ type: String,
67
+ required: false,
68
+ default: null
69
+ },
70
+ label: {
71
+ type: [String, Function],
72
+ required: false,
73
+ default: null
74
+ },
75
+ appendIcon: {
76
+ type: String,
77
+ required: false,
78
+ default: null
79
+ },
80
+ icon: {
81
+ type: String,
82
+ required: false,
83
+ default: null
84
+ },
85
+ variant: {
86
+ type: String as PropType<"standard" | "full">,
87
+ required: false,
88
+ default: "full"
89
+ },
90
+ color: {
91
+ type: String as PropType<ColorBase>,
92
+ required: false,
93
+ default: ColorEnum.Primary
94
+ },
95
+ load: {
96
+ type: Boolean,
97
+ required: false,
98
+ default: false
99
+ },
100
+ editable: {
101
+ type: Boolean,
102
+ required: false,
103
+ default: true
104
+ }
105
+ },
106
+ emits: ["click"],
107
+ setup(props, { emit }) {
108
+ const { getColors } = useColors();
109
+
110
+ const colors = computed(() => getColors(props.color));
111
+
112
+ const width = computed((): string => {
113
+ if (props.label) {
114
+ return "fit-content";
115
+ }
116
+ return "72px";
117
+ });
118
+
119
+ const onClick = (event: MouseEvent) => {
120
+ if (props.editable && !props.load) {
121
+ emit("click", event);
122
+ }
123
+ };
124
+
125
+ return {
126
+ colors,
127
+ width,
128
+ onClick
129
+ };
130
+ }
131
+ })
132
+ </script>
@@ -15,6 +15,7 @@
15
15
  />
16
16
  <FSButtonPreviousIcon
17
17
  :color="ColorEnum.Dark"
18
+ @click="goToPrev"
18
19
  />
19
20
  </template>
20
21
  <template #default>
@@ -28,6 +29,7 @@
28
29
  <template #next>
29
30
  <FSButtonNextIcon
30
31
  :color="ColorEnum.Dark"
32
+ @click="goToNext"
31
33
  />
32
34
  <FSButton
33
35
  v-if="$props.dash"
@@ -71,7 +73,12 @@ export default defineComponent({
71
73
  dash: {
72
74
  type: Boolean,
73
75
  required: false,
74
- default: true
76
+ default: false
77
+ },
78
+ speed: {
79
+ type: Number,
80
+ required: false,
81
+ default: 250
75
82
  }
76
83
  },
77
84
  setup(props) {
@@ -96,6 +103,12 @@ export default defineComponent({
96
103
  }
97
104
  };
98
105
 
106
+ const goToPrev = () => {
107
+ if (slideGroupRef.value) {
108
+ slideGroupRef.value.scrollOffset = Math.max(0, slideGroupRef.value.scrollOffset - props.speed);
109
+ }
110
+ };
111
+
99
112
  const goToEnd = () => {
100
113
  if (slideGroupRef.value) {
101
114
  const contentSize = slideGroupRef.value.$el.children[1].children[0].clientWidth;
@@ -105,12 +118,23 @@ export default defineComponent({
105
118
  }
106
119
  };
107
120
 
121
+ const goToNext = () => {
122
+ if (slideGroupRef.value) {
123
+ const contentSize = slideGroupRef.value.$el.children[1].children[0].clientWidth;
124
+ const containerSize = slideGroupRef.value.$el.clientWidth;
125
+ const arrowsOffset = props.dash ? 104 : 64;
126
+ slideGroupRef.value.scrollOffset = Math.min(contentSize - containerSize + arrowsOffset, slideGroupRef.value.scrollOffset + props.speed);
127
+ }
128
+ };
129
+
108
130
  return {
109
131
  slideGroupRef,
110
132
  ColorEnum,
111
133
  style,
112
134
  getChildren,
113
135
  goToStart,
136
+ goToPrev,
137
+ goToNext,
114
138
  goToEnd
115
139
  };
116
140
  }
@@ -40,23 +40,22 @@ export default defineComponent({
40
40
  }
41
41
  },
42
42
  setup(props) {
43
- const { getColors, getContrasts } = useColors();
44
43
  const { getChildren } = useSlots();
44
+ const { getColors } = useColors();
45
45
 
46
- const textColors = computed(() => getContrasts(props.color));
47
46
  const colors = computed(() => getColors(props.color));
48
47
  const darks = getColors(ColorEnum.Dark);
49
48
 
50
49
  const style = computed((): { [code: string]: string } & Partial<CSSStyleDeclaration> => ({
51
50
  "--fs-group-color" : darks.base,
51
+ "--fs-group-disabled-color" : darks.light,
52
52
  "--fs-group-hover-background-color": colors.value.light,
53
53
  "--fs-group-hover-color" : darks.dark,
54
- "--fs-group-disabled-color" : darks.light,
55
54
  "--fs-group-light" : colors.value.light,
56
55
  "--fs-group-base" : colors.value.base,
57
56
  "--fs-group-dark" : colors.value.dark,
58
57
  "--fs-tab-tag-background-color" : colors.value.base,
59
- "--fs-tab-tag-color" : textColors.value.light
58
+ "--fs-tab-tag-color" : colors.value.baseContrast
60
59
  }));
61
60
 
62
61
  return {
@@ -73,28 +73,27 @@ export default defineComponent({
73
73
  },
74
74
  emits: ["remove"],
75
75
  setup(props) {
76
- const { getColors, getContrasts } = useColors();
76
+ const { getColors } = useColors();
77
77
 
78
- const textColors = computed(() => getContrasts(props.color));
79
78
  const colors = computed(() => getColors(props.color));
80
79
 
81
80
  const style = computed((): { [code: string]: string } & Partial<CSSStyleDeclaration> => {
82
81
  switch (props.variant) {
83
82
  case "standard": return {
84
83
  "--fs-tag-background-color" : colors.value.light,
85
- "--fs-tag-color" : textColors.value.base,
84
+ "--fs-tag-color" : colors.value.lightContrast,
86
85
  "--fs-tag-hover-background-color" : colors.value.base,
87
- "--fs-tag-hover-color" : textColors.value.light,
86
+ "--fs-tag-hover-color" : colors.value.baseContrast,
88
87
  "--fs-tag-active-background-color": colors.value.dark,
89
- "--fs-tag-active-color" : textColors.value.light
88
+ "--fs-tag-active-color" : colors.value.darkContrast
90
89
  };
91
90
  case "full": return {
92
91
  "--fs-tag-background-color" : colors.value.base,
93
- "--fs-tag-color" : textColors.value.light,
92
+ "--fs-tag-color" : colors.value.baseContrast,
94
93
  "--fs-tag-hover-background-color" : colors.value.base,
95
- "--fs-tag-hover-color" : textColors.value.light,
94
+ "--fs-tag-hover-color" : colors.value.baseContrast,
96
95
  "--fs-tag-active-background-color": colors.value.dark,
97
- "--fs-tag-active-color" : textColors.value.light
96
+ "--fs-tag-active-color" : colors.value.darkContrast
98
97
  };
99
98
  }
100
99
  });
@@ -16,6 +16,7 @@
16
16
  :color="getColor(item)"
17
17
  :class="getClass(item)"
18
18
  :label="item.label"
19
+ :icon="item.icon"
19
20
  :key="index"
20
21
  @click="toggle(item)"
21
22
  />
@@ -56,6 +57,7 @@
56
57
  :color="getColor(item)"
57
58
  :class="getClass(item)"
58
59
  :label="item.label"
60
+ :icon="label.icon"
59
61
  :key="index"
60
62
  @click="toggle(item)"
61
63
  />
@@ -50,26 +50,10 @@ export default defineComponent({
50
50
  "--fs-group-hover-color": darks.dark
51
51
  }));
52
52
 
53
- const goToStart = () => {
54
- if (wrapGroupRef.value) {
55
- wrapGroupRef.value.scrollOffset = 0;
56
- }
57
- };
58
-
59
- const goToEnd = () => {
60
- if (wrapGroupRef.value) {
61
- const contentSize = wrapGroupRef.value.$el.children[1].children[0].clientWidth;
62
- const containerSize = wrapGroupRef.value.$el.clientWidth;
63
- wrapGroupRef.value.scrollOffset = (contentSize - containerSize);
64
- }
65
- };
66
-
67
53
  return {
68
54
  wrapGroupRef,
69
55
  style,
70
- getChildren,
71
- goToStart,
72
- goToEnd
56
+ getChildren
73
57
  };
74
58
  }
75
59
  });
@@ -123,7 +123,7 @@ export default defineComponent({
123
123
  },
124
124
  emits: ["update:modelValue"],
125
125
  setup(props) {
126
- const {validateOn, blurred, getMessages} = useRules();
126
+ const { validateOn, blurred, getMessages } = useRules();
127
127
  const { getColors } = useColors();
128
128
 
129
129
  const errors = getColors(ColorEnum.Error);