@dative-gpi/foundation-shared-components 0.0.11 → 0.0.13

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 (98) hide show
  1. package/aliases/FSButton.ts +8 -6
  2. package/components/FSBreadcrumbs.vue +3 -1
  3. package/components/FSButton.vue +13 -10
  4. package/components/FSCalendar.vue +4 -3
  5. package/components/FSCalendarTwin.vue +4 -3
  6. package/components/FSCarousel.vue +3 -1
  7. package/components/FSCheckbox.vue +8 -6
  8. package/components/FSChip.vue +5 -3
  9. package/components/FSClock.vue +50 -34
  10. package/components/FSColor.vue +3 -1
  11. package/components/FSColorIcon.vue +3 -1
  12. package/components/FSContainer.vue +4 -2
  13. package/components/FSDivider.vue +49 -8
  14. package/components/FSFadeOut.vue +3 -1
  15. package/components/FSFileButton.vue +4 -3
  16. package/components/FSForm.vue +52 -0
  17. package/components/FSImage.vue +42 -33
  18. package/components/FSLabel.vue +105 -0
  19. package/components/FSLink.vue +95 -0
  20. package/components/FSPagination.vue +96 -0
  21. package/components/FSPermissions.vue +0 -0
  22. package/components/FSRadio.vue +8 -6
  23. package/components/FSRemoveDialog.vue +1 -1
  24. package/components/FSSlideGroup.vue +2 -1
  25. package/components/FSSlider.vue +5 -3
  26. package/components/FSSubmitDialog.vue +2 -2
  27. package/components/FSSwitch.vue +9 -7
  28. package/components/FSTabs.vue +4 -3
  29. package/components/FSTag.vue +4 -2
  30. package/components/FSText.vue +3 -2
  31. package/components/FSWrapGroup.vue +2 -1
  32. package/components/deviceOrganisations/FSConnectivity.vue +2 -1
  33. package/components/deviceOrganisations/FSWorstAlert.vue +2 -1
  34. package/components/{FSAutocompleteField.vue → fields/FSAutocompleteField.vue} +25 -22
  35. package/components/fields/FSColorField.vue +194 -0
  36. package/components/{FSDateField.vue → fields/FSDateField.vue} +18 -52
  37. package/components/{FSDateRangeField.vue → fields/FSDateRangeField.vue} +22 -67
  38. package/components/{FSDateTimeField.vue → fields/FSDateTimeField.vue} +20 -54
  39. package/components/{FSDateTimeRangeField.vue → fields/FSDateTimeRangeField.vue} +27 -70
  40. package/components/{FSIconField.vue → fields/FSIconField.vue} +20 -53
  41. package/components/{FSNumberField.vue → fields/FSNumberField.vue} +0 -24
  42. package/components/{FSPasswordField.vue → fields/FSPasswordField.vue} +9 -31
  43. package/components/{FSRichTextField.vue → fields/FSRichTextField.vue} +10 -9
  44. package/components/{FSSearchField.vue → fields/FSSearchField.vue} +47 -14
  45. package/components/{FSSelectField.vue → fields/FSSelectField.vue} +22 -24
  46. package/components/{FSTagField.vue → fields/FSTagField.vue} +19 -53
  47. package/components/{FSTextArea.vue → fields/FSTextArea.vue} +28 -27
  48. package/components/{FSTextField.vue → fields/FSTextField.vue} +23 -21
  49. package/components/fields/FSTimeField.vue +104 -0
  50. package/components/fields/FSTimeSlotField.vue +263 -0
  51. package/components/lists/FSDataTableUI.vue +7 -6
  52. package/components/lists/FSFilterButton.vue +25 -17
  53. package/components/lists/FSHiddenButton.vue +1 -0
  54. package/components/lists/FSLoadDataTable.vue +88 -0
  55. package/components/tiles/FSDeviceOrganisationTileUI.vue +5 -10
  56. package/components/tiles/FSGroupTileUI.vue +5 -10
  57. package/components/{FSLoadTile.vue → tiles/FSLoadTile.vue} +9 -7
  58. package/components/{FSTile.vue → tiles/FSTile.vue} +5 -4
  59. package/composables/index.ts +2 -0
  60. package/composables/useBreakpoints.ts +7 -5
  61. package/composables/useDebounce.ts +22 -0
  62. package/composables/useRules.ts +72 -0
  63. package/elements/FSFormElement.ts +17 -0
  64. package/icons/flags/France.vue +9 -0
  65. package/icons/flags/Germany.vue +7 -0
  66. package/icons/flags/GreatBritain.vue +9 -0
  67. package/icons/flags/Italy.vue +9 -0
  68. package/icons/flags/Portugal.vue +59 -0
  69. package/icons/flags/Spain.vue +546 -0
  70. package/icons/flags/UnitedStates.vue +12 -0
  71. package/icons/sets.ts +17 -0
  72. package/models/rules.ts +10 -1
  73. package/package.json +6 -4
  74. package/pages/FSExternalIdentityButton.vue +64 -0
  75. package/pages/FSLanguageSetter.vue +140 -0
  76. package/pages/FSLoginPage.vue +253 -0
  77. package/styles/components/fs_clock.scss +4 -0
  78. package/styles/components/fs_color_field.scss +17 -0
  79. package/styles/components/fs_divider.scss +5 -0
  80. package/styles/components/fs_image.scss +12 -1
  81. package/styles/components/fs_label.scss +86 -0
  82. package/styles/components/fs_link.scss +6 -0
  83. package/styles/components/fs_load_data_table.scss +77 -0
  84. package/styles/components/fs_pagination.scss +11 -0
  85. package/styles/components/fs_time_field.scss +3 -0
  86. package/styles/components/fs_timeslot_field.scss +75 -0
  87. package/styles/components/index.scss +7 -0
  88. package/styles/globals/text_fonts.scss +18 -0
  89. package/styles/main.scss +3 -1
  90. package/styles/pages/fs_language_setter.scss +55 -0
  91. package/styles/pages/index.scss +1 -0
  92. package/utils/color.ts +7 -0
  93. package/utils/css.ts +2 -1
  94. package/utils/index.ts +3 -1
  95. package/utils/time.ts +29 -0
  96. package/components/FSHeaderButton.vue +0 -17
  97. package/components/lists/FSDataIteratorGroup.vue +0 -7
  98. package/index.ts +0 -6
@@ -7,45 +7,16 @@
7
7
  :hideHeader="$props.hideHeader"
8
8
  :required="$props.required"
9
9
  :editable="$props.editable"
10
- :error="messages.length > 0"
11
10
  :readonly="true"
12
- :modelValue="placeholder"
11
+ :rules="$props.rules"
12
+ :messages="messages"
13
+ :validateOn="validateOn"
14
+ :validationValue="$props.modelValue"
15
+ :modelValue="toShortTimeFormat"
13
16
  @click="onClick"
14
17
  @click:clear="onClear"
18
+ @blur="blurred = true"
15
19
  >
16
- <template v-if="!$props.hideHeader" #label>
17
- <slot name="label">
18
- <FSRow :wrap="false">
19
- <FSSpan
20
- v-if="$props.label"
21
- class="fs-date-field-label"
22
- font="text-overline"
23
- :style="style"
24
- >
25
- {{ $props.label }}
26
- </FSSpan>
27
- <FSSpan
28
- v-if="$props.label && $props.required"
29
- class="fs-date-field-label"
30
- style="margin-left: -8px;"
31
- font="text-overline"
32
- :ellipsis="false"
33
- :style="style"
34
- >
35
- *
36
- </FSSpan>
37
- <v-spacer style="min-width: 40px;" />
38
- <FSSpan
39
- v-if="messages.length > 0"
40
- class="fs-date-field-messages"
41
- font="text-overline"
42
- :style="style"
43
- >
44
- {{ messages.join(", ") }}
45
- </FSSpan>
46
- </FSRow>
47
- </slot>
48
- </template>
49
20
  <template #prepend-inner>
50
21
  <slot name="prepend-inner">
51
22
  <FSButton
@@ -94,17 +65,18 @@
94
65
  <script lang="ts">
95
66
  import { computed, defineComponent, PropType, ref } from "vue";
96
67
 
68
+ import { useColors, useRules } from "@dative-gpi/foundation-shared-components/composables";
97
69
  import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
98
70
  import { useTimeZone } from "@dative-gpi/foundation-shared-services/composables";
99
- import { useColors } from "@dative-gpi/foundation-shared-components/composables";
100
71
 
101
- import FSSubmitDialog from "./FSSubmitDialog.vue";
102
- import FSCalendarTwin from "./FSCalendarTwin.vue";
72
+ import FSSubmitDialog from "../FSSubmitDialog.vue";
73
+ import FSCalendarTwin from "../FSCalendarTwin.vue";
103
74
  import FSTextField from "./FSTextField.vue";
104
- import FSButton from "./FSButton.vue";
105
- import FSClock from "./FSClock.vue";
106
- import FSCard from "./FSCard.vue";
107
- import FSCol from "./FSCol.vue";
75
+ import FSButton from "../FSButton.vue";
76
+ import FSClock from "../FSClock.vue";
77
+ import FSCard from "../FSCard.vue";
78
+ import FSCol from "../FSCol.vue";
79
+ import FSRow from "../FSRow.vue";
108
80
 
109
81
  export default defineComponent({
110
82
  name: "FSDateTimeRangeField",
@@ -115,7 +87,8 @@ export default defineComponent({
115
87
  FSButton,
116
88
  FSClock,
117
89
  FSCard,
118
- FSCol
90
+ FSCol,
91
+ FSRow
119
92
  },
120
93
  props: {
121
94
  label: {
@@ -162,10 +135,12 @@ export default defineComponent({
162
135
  emits: ["update:modelValue"],
163
136
  setup(props, { emit }) {
164
137
  const { getUserOffsetMillis, epochToShortTimeFormat } = useTimeZone();
138
+ const { validateOn, blurred, getMessages } = useRules();
139
+ const { getColors } = useColors();
165
140
 
166
- const errors = useColors().getColors(ColorEnum.Error);
167
- const lights = useColors().getColors(ColorEnum.Light);
168
- const darks = useColors().getColors(ColorEnum.Dark);
141
+ const errors = getColors(ColorEnum.Error);
142
+ const lights = getColors(ColorEnum.Light);
143
+ const darks = getColors(ColorEnum.Dark);
169
144
 
170
145
  const dialog = ref(false);
171
146
 
@@ -203,35 +178,13 @@ export default defineComponent({
203
178
  };
204
179
  });
205
180
 
206
- const placeholder = computed((): string => {
181
+ const toShortTimeFormat = computed((): string => {
207
182
  if (!props.modelValue || !Array.isArray(props.modelValue) || !props.modelValue.length) {
208
183
  return "";
209
184
  }
210
185
  return props.modelValue.map((epoch) => epochToShortTimeFormat(epoch)).join(" - ");
211
186
  });
212
187
 
213
- const messages = computed((): string[] => {
214
- const messages = [];
215
- for (const rule of props.rules) {
216
- if (props.modelValue && Array.isArray(props.modelValue)) {
217
- for (const value of props.modelValue) {
218
- const message = rule(value);
219
- if (typeof(message) === "string") {
220
- messages.push(message);
221
- break;
222
- }
223
- }
224
- }
225
- else {
226
- const message = rule(null);
227
- if (typeof(message) === "string") {
228
- messages.push(message);
229
- }
230
- }
231
- }
232
- return messages;
233
- });
234
-
235
188
  const innerDateLeft = computed((): number | null => {
236
189
  if (innerDateRange.value && Array.isArray(innerDateRange.value) && innerDateRange.value.length) {
237
190
  return innerDateRange.value[0];
@@ -246,6 +199,8 @@ export default defineComponent({
246
199
  return null;
247
200
  });
248
201
 
202
+ const messages = computed((): string[] => getMessages(props.modelValue, props.rules, true));
203
+
249
204
  const onClick = (): void => {
250
205
  if (props.editable) {
251
206
  dialog.value = true;
@@ -268,10 +223,12 @@ export default defineComponent({
268
223
 
269
224
  return {
270
225
  ColorEnum,
226
+ validateOn,
271
227
  messages,
228
+ blurred,
272
229
  style,
273
230
  dialog,
274
- placeholder,
231
+ toShortTimeFormat,
275
232
  innerDateLeft,
276
233
  innerTimeLeft,
277
234
  innerDateRight,
@@ -6,43 +6,14 @@
6
6
  :hideHeader="$props.hideHeader"
7
7
  :required="$props.required"
8
8
  :editable="$props.editable"
9
- :error="messages.length > 0"
9
+ :rules="$props.rules"
10
+ :messages="messages"
11
+ :validateOn="validateOn"
12
+ :validationValue="$props.modelValue"
13
+ @blur="blurred = true"
10
14
  v-model="innerValue"
11
15
  v-bind="$attrs"
12
16
  >
13
- <template v-if="!$props.hideHeader" #label>
14
- <slot name="label">
15
- <FSRow :wrap="false">
16
- <FSSpan
17
- v-if="$props.label"
18
- class="fs-icon-field-label"
19
- font="text-overline"
20
- :style="style"
21
- >
22
- {{ $props.label }}
23
- </FSSpan>
24
- <FSSpan
25
- v-if="$props.label && $props.required"
26
- class="fs-icon-field-label"
27
- style="margin-left: -8px;"
28
- font="text-overline"
29
- :ellipsis="false"
30
- :style="style"
31
- >
32
- *
33
- </FSSpan>
34
- <v-spacer style="min-width: 40px;" />
35
- <FSSpan
36
- v-if="messages.length > 0"
37
- class="fs-icon-field-messages"
38
- font="text-overline"
39
- :style="style"
40
- >
41
- {{ messages.join(", ") }}
42
- </FSSpan>
43
- </FSRow>
44
- </slot>
45
- </template>
46
17
  <template #append-inner>
47
18
  <FSIcon
48
19
  v-if="$props.modelValue"
@@ -70,20 +41,20 @@
70
41
  import { computed, defineComponent, PropType, ref } from "vue";
71
42
 
72
43
  import { Icons, sortByLevenshteinDistance } from "@dative-gpi/foundation-shared-components/utils";
44
+ import { useColors, useRules } from "@dative-gpi/foundation-shared-components/composables";
73
45
  import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
74
- import { useColors } from "@dative-gpi/foundation-shared-components/composables";
75
46
  import { FSToggle } from "@dative-gpi/foundation-shared-components/models";
76
47
 
48
+ import FSToggleSet from "../FSToggleSet.vue";
77
49
  import FSTextField from "./FSTextField.vue";
78
- import FSToggleSet from "./FSToggleSet.vue";
79
- import FSIcon from "./FSIcon.vue";
80
- import FSCol from "./FSCol.vue";
50
+ import FSIcon from "../FSIcon.vue";
51
+ import FSCol from "../FSCol.vue";
81
52
 
82
53
  export default defineComponent({
83
54
  name: "FSIconField",
84
55
  components: {
85
- FSTextField,
86
56
  FSToggleSet,
57
+ FSTextField,
87
58
  FSIcon,
88
59
  FSCol,
89
60
  },
@@ -151,9 +122,12 @@ export default defineComponent({
151
122
  },
152
123
  emits: ["update:modelValue"],
153
124
  setup(props) {
154
- const errors = useColors().getColors(ColorEnum.Error);
155
- const lights = useColors().getColors(ColorEnum.Light);
156
- const darks = useColors().getColors(ColorEnum.Dark);
125
+ const {validateOn, blurred, getMessages} = useRules();
126
+ const { getColors } = useColors();
127
+
128
+ const errors = getColors(ColorEnum.Error);
129
+ const lights = getColors(ColorEnum.Light);
130
+ const darks = getColors(ColorEnum.Dark);
157
131
 
158
132
  const innerValue = ref(null);
159
133
 
@@ -169,17 +143,6 @@ export default defineComponent({
169
143
  };
170
144
  });
171
145
 
172
- const messages = computed((): string[] => {
173
- const messages = [];
174
- for (const rule of props.rules) {
175
- const message = rule(props.modelValue);
176
- if (typeof(message) === "string") {
177
- messages.push(message);
178
- }
179
- }
180
- return messages;
181
- });
182
-
183
146
  const icons = computed((): FSToggle[] => {
184
147
  const innerIcons: FSToggle[] = [];
185
148
  if (!innerValue.value || innerValue.value.length < 3) {
@@ -221,9 +184,13 @@ export default defineComponent({
221
184
  return innerIcons;
222
185
  });
223
186
 
187
+ const messages = computed((): string[] => getMessages(props.modelValue, props.rules));
188
+
224
189
  return {
225
190
  innerValue,
191
+ validateOn,
226
192
  messages,
193
+ blurred,
227
194
  style,
228
195
  icons
229
196
  };
@@ -1,10 +1,6 @@
1
1
  <template>
2
2
  <FSTextField
3
3
  type="number"
4
- :label="$props.label"
5
- :description="$props.description"
6
- :hideHeader="$props.hideHeader"
7
- :required="$props.required"
8
4
  :editable="$props.editable"
9
5
  :modelValue="$props.modelValue?.toString()"
10
6
  @update:modelValue="(value) => $emit('update:modelValue', isNaN(parseFloat(value)) ? 0 : parseFloat(value))"
@@ -27,31 +23,11 @@ export default defineComponent({
27
23
  FSTextField
28
24
  },
29
25
  props: {
30
- label: {
31
- type: String,
32
- required: false,
33
- default: null
34
- },
35
- description: {
36
- type: String,
37
- required: false,
38
- default: null
39
- },
40
26
  modelValue: {
41
27
  type: Number,
42
28
  required: false,
43
29
  default: null
44
30
  },
45
- hideHeader: {
46
- type: Boolean,
47
- required: false,
48
- default: false
49
- },
50
- required: {
51
- type: Boolean,
52
- required: false,
53
- default: false
54
- },
55
31
  editable: {
56
32
  type: Boolean,
57
33
  required: false,
@@ -1,29 +1,25 @@
1
1
  <template>
2
2
  <FSTextField
3
- :label="$props.label"
4
- :description="$props.description"
5
3
  :type="type"
6
- :hideHeader="$props.hideHeader"
7
- :required="$props.required"
8
4
  :editable="$props.editable"
9
5
  :modelValue="$props.modelValue"
10
6
  @update:modelValue="(value) => $emit('update:modelValue', value)"
11
7
  v-bind="$attrs"
12
8
  >
9
+ <template v-for="(_, name) in $slots" v-slot:[name]="slotData">
10
+ <slot :name="name" v-bind="slotData" />
11
+ </template>
13
12
  <template #append-inner>
14
13
  <slot name="append-inner">
15
14
  <FSButton
16
15
  variant="icon"
17
- :icon="icon"
18
16
  :editable="$props.editable"
19
17
  :color="ColorEnum.Dark"
18
+ :icon="icon"
20
19
  @click="onToggle"
21
20
  />
22
21
  </slot>
23
22
  </template>
24
- <template v-for="(_, name) in $slots" v-slot:[name]="slotData">
25
- <slot :name="name" v-bind="slotData" />
26
- </template>
27
23
  </FSTextField>
28
24
  </template>
29
25
 
@@ -34,7 +30,7 @@ import { useColors } from "@dative-gpi/foundation-shared-components/composables"
34
30
  import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
35
31
 
36
32
  import FSTextField from "./FSTextField.vue";
37
- import FSButton from "./FSButton.vue";
33
+ import FSButton from "../FSButton.vue";
38
34
 
39
35
  export default defineComponent({
40
36
  name: "FSPasswordField",
@@ -43,31 +39,11 @@ export default defineComponent({
43
39
  FSButton
44
40
  },
45
41
  props: {
46
- label: {
47
- type: String,
48
- required: false,
49
- default: null
50
- },
51
- description: {
52
- type: String,
53
- required: false,
54
- default: null
55
- },
56
42
  modelValue: {
57
43
  type: String,
58
44
  required: false,
59
45
  default: null
60
46
  },
61
- hideHeader: {
62
- type: Boolean,
63
- required: false,
64
- default: false
65
- },
66
- required: {
67
- type: Boolean,
68
- required: false,
69
- default: false
70
- },
71
47
  editable: {
72
48
  type: Boolean,
73
49
  required: false,
@@ -76,8 +52,10 @@ export default defineComponent({
76
52
  },
77
53
  emits: ["update:modelValue"],
78
54
  setup(props) {
79
- const lights = useColors().getColors(ColorEnum.Light);
80
- const darks = useColors().getColors(ColorEnum.Dark);
55
+ const { getColors } = useColors();
56
+
57
+ const lights = getColors(ColorEnum.Light);
58
+ const darks = getColors(ColorEnum.Dark);
81
59
 
82
60
  const stars = ref(true);
83
61
 
@@ -141,10 +141,10 @@
141
141
  :contenteditable="!readonly && $props.editable"
142
142
  />
143
143
  <FSTextField
144
- v-if="isLink && $props.editable"
145
- v-model="linkUrl"
144
+ v-if="isLink && !readonly && $props.editable"
146
145
  :hideHeader="true"
147
146
  @keypress.enter.stop="toggleLink"
147
+ v-model="linkUrl"
148
148
  />
149
149
  <slot name="description">
150
150
  <FSSpan
@@ -172,9 +172,9 @@ import { getAncestor, getSelectedNode } from "@dative-gpi/foundation-shared-comp
172
172
  import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
173
173
 
174
174
  import FSTextField from "./FSTextField.vue";
175
- import FSIcon from "./FSIcon.vue";
176
- import FSCol from "./FSCol.vue";
177
- import FSRow from "./FSRow.vue";
175
+ import FSIcon from "../FSIcon.vue";
176
+ import FSCol from "../FSCol.vue";
177
+ import FSRow from "../FSRow.vue";
178
178
 
179
179
  export default defineComponent({
180
180
  name: "FSRichTextField",
@@ -229,10 +229,11 @@ export default defineComponent({
229
229
  emits: ["update:modelValue"],
230
230
  setup(props, { emit }) {
231
231
  const { isMobileSized } = useBreakpoints();
232
+ const { getColors } = useColors();
232
233
 
233
- const linkColors = computed(()=> useColors().getColors(props.linkColor));
234
- const lights = useColors().getColors(ColorEnum.Light);
235
- const darks = useColors().getColors(ColorEnum.Dark);
234
+ const linkColors = computed(()=> getColors(props.linkColor));
235
+ const lights = getColors(ColorEnum.Light);
236
+ const darks = getColors(ColorEnum.Dark);
236
237
 
237
238
  const canUndo = ref(false);
238
239
  const isLink = ref(false);
@@ -287,7 +288,7 @@ export default defineComponent({
287
288
  });
288
289
 
289
290
  const readonly = computed((): boolean => {
290
- return props.variant === "readonly";
291
+ return ["readonly"].includes(props.variant);
291
292
  });
292
293
 
293
294
  const style = computed((): {[code: string]: string} & Partial<CSSStyleDeclaration> => {
@@ -6,18 +6,27 @@
6
6
  :hideHeader="$props.hideHeader"
7
7
  :required="$props.required"
8
8
  :editable="$props.editable"
9
+ :placeholder="placeholder"
9
10
  @keydown.enter="$emit('update:modelValue', innerValue)"
10
11
  v-model="innerValue"
11
12
  v-bind="$attrs"
12
13
  >
13
- <template
14
- v-if="!$props.instant"
15
- #append
16
- >
14
+ <template v-if="$props.prependInnerIcon" #prepend-inner>
15
+ <slot name="prepend-inner">
16
+ <FSButton
17
+ variant="icon"
18
+ :icon="$props.prependInnerIcon"
19
+ :editable="$props.editable"
20
+ :color="ColorEnum.Dark"
21
+ @click="$emit('update:modelValue', innerValue)"
22
+ />
23
+ </slot>
24
+ </template>
25
+ <template v-if="!['instant'].includes($props.variant)" #append>
17
26
  <slot name="append">
18
27
  <FSButton
19
28
  :prependIcon="$props.buttonPrependIcon"
20
- :label="$props.buttonLabel"
29
+ :label="buttonLabel"
21
30
  :appendIcon="$props.buttonAppendIcon"
22
31
  :variant="$props.buttonVariant"
23
32
  :color="$props.buttonColor"
@@ -33,12 +42,13 @@
33
42
  </template>
34
43
 
35
44
  <script lang="ts">
36
- import { defineComponent, PropType, ref, watch } from "vue";
45
+ import { computed, defineComponent, PropType, ref, watch } from "vue";
37
46
 
47
+ import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
38
48
  import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
39
49
 
40
50
  import FSTextField from "./FSTextField.vue";
41
- import FSButton from "./FSButton.vue";
51
+ import FSButton from "../FSButton.vue";
42
52
 
43
53
  export default defineComponent({
44
54
  name: "FSSearchField",
@@ -57,11 +67,26 @@ export default defineComponent({
57
67
  required: false,
58
68
  default: null
59
69
  },
60
- buttonPrependIcon: {
70
+ placeholder: {
71
+ type: String,
72
+ required: false,
73
+ default: null
74
+ },
75
+ prependInnerIcon: {
61
76
  type: String,
62
77
  required: false,
63
78
  default: "mdi-magnify"
64
79
  },
80
+ variant: {
81
+ type: String as PropType<"standard" | "instant">,
82
+ required: false,
83
+ default: "instant"
84
+ },
85
+ buttonPrependIcon: {
86
+ type: String,
87
+ required: false,
88
+ default: null
89
+ },
65
90
  buttonLabel: {
66
91
  type: String,
67
92
  required: false,
@@ -97,11 +122,6 @@ export default defineComponent({
97
122
  required: false,
98
123
  default: false
99
124
  },
100
- instant: {
101
- type: Boolean,
102
- required: false,
103
- default: true
104
- },
105
125
  required: {
106
126
  type: Boolean,
107
127
  required: false,
@@ -115,15 +135,28 @@ export default defineComponent({
115
135
  },
116
136
  emits: ["update:modelValue"],
117
137
  setup(props, { emit }) {
138
+ const { $tr } = useTranslationsProvider();
139
+
118
140
  const innerValue = ref(props.modelValue);
119
141
 
142
+ const placeholder = computed(() => {
143
+ return props.placeholder ?? $tr('ui.search.placeholder', 'Search...');
144
+ });
145
+
146
+ const buttonLabel = computed(() => {
147
+ return props.buttonLabel ?? $tr('ui.button.search', 'Search');
148
+ });
149
+
120
150
  watch(innerValue, () => {
121
- if (props.instant) {
151
+ if (["instant"].includes(props.variant)) {
122
152
  emit("update:modelValue", innerValue.value);
123
153
  }
124
154
  });
125
155
 
126
156
  return {
157
+ ColorEnum,
158
+ placeholder,
159
+ buttonLabel,
127
160
  innerValue
128
161
  };
129
162
  }
@@ -36,16 +36,18 @@
36
36
  menuIcon="mdi-chevron-down"
37
37
  clearIcon="mdi-close"
38
38
  variant="outlined"
39
+ :style="style"
39
40
  :hideDetails="true"
40
41
  :items="$props.items"
41
42
  :itemTitle="$props.itemTitle"
42
43
  :itemValue="$props.itemValue"
43
44
  :readonly="!$props.editable"
44
45
  :clearable="$props.editable && $props.clearable"
45
- :error="messages.length > 0"
46
- :style="style"
46
+ :rules="$props.rules"
47
+ :validateOn="validateOn"
47
48
  :modelValue="$props.modelValue"
48
49
  @update:modelValue="(value) => $emit('update:modelValue', value)"
50
+ @blur="blurred = true"
49
51
  v-bind="$attrs"
50
52
  >
51
53
  <template v-for="(_, name) in slots" v-slot:[name]="slotData">
@@ -68,12 +70,12 @@
68
70
  <script lang="ts">
69
71
  import { computed, defineComponent, PropType } from "vue";
70
72
 
71
- import { useColors, useSlots } from "@dative-gpi/foundation-shared-components/composables";
73
+ import { useColors, useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
72
74
  import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
73
75
 
74
- import FSSpan from "./FSSpan.vue";
75
- import FSCol from "./FSCol.vue";
76
- import FSRow from "./FSRow.vue";
76
+ import FSSpan from "../FSSpan.vue";
77
+ import FSCol from "../FSCol.vue";
78
+ import FSRow from "../FSRow.vue";
77
79
 
78
80
  export default defineComponent({
79
81
  name: "FSSelectField",
@@ -122,16 +124,16 @@ export default defineComponent({
122
124
  required: false,
123
125
  default: false
124
126
  },
125
- clearable: {
126
- type: Boolean,
127
- required: false,
128
- default: true
129
- },
130
127
  rules: {
131
128
  type: Array as PropType<Function[]>,
132
129
  required: false,
133
130
  default: () => []
134
131
  },
132
+ messages: {
133
+ type: Array as PropType<string[]>,
134
+ required: false,
135
+ default: null
136
+ },
135
137
  editable: {
136
138
  type: Boolean,
137
139
  required: false,
@@ -140,13 +142,16 @@ export default defineComponent({
140
142
  },
141
143
  emits: ["update:modelValue"],
142
144
  setup(props) {
145
+ const { validateOn, blurred, getMessages } = useRules();
146
+ const { getColors } = useColors();
143
147
  const { slots } = useSlots();
148
+
144
149
  delete slots.label;
145
150
  delete slots.description;
146
151
 
147
- const errors = useColors().getColors(ColorEnum.Error);
148
- const lights = useColors().getColors(ColorEnum.Light);
149
- const darks = useColors().getColors(ColorEnum.Dark);
152
+ const errors = getColors(ColorEnum.Error);
153
+ const lights = getColors(ColorEnum.Light);
154
+ const darks = getColors(ColorEnum.Dark);
150
155
 
151
156
  const style = computed((): {[code: string]: string} & Partial<CSSStyleDeclaration> => {
152
157
  if (!props.editable) {
@@ -167,19 +172,12 @@ export default defineComponent({
167
172
  };
168
173
  });
169
174
 
170
- const messages = computed((): string[] => {
171
- const messages = [];
172
- for (const rule of props.rules) {
173
- const message = rule(props.modelValue ?? "");
174
- if (typeof(message) === "string") {
175
- messages.push(message);
176
- }
177
- }
178
- return messages;
179
- });
175
+ const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
180
176
 
181
177
  return {
178
+ validateOn,
182
179
  messages,
180
+ blurred,
183
181
  slots,
184
182
  style
185
183
  };