@dative-gpi/foundation-shared-components 0.0.12 → 0.0.14
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/components/FSButton.vue +1 -1
- package/components/FSCalendarTwin.vue +2 -0
- package/components/FSCheckbox.vue +3 -3
- package/components/FSClock.vue +47 -40
- package/components/FSCol.vue +2 -2
- package/components/FSDivider.vue +46 -7
- package/components/FSForm.vue +52 -0
- package/components/FSImage.vue +41 -32
- package/components/FSLabel.vue +105 -0
- package/components/FSPagination.vue +25 -9
- package/components/FSPermissions.vue +0 -0
- package/components/FSRadio.vue +3 -3
- package/components/FSSlideGroup.vue +10 -11
- package/components/FSSubmitDialog.vue +1 -1
- package/components/FSSwitch.vue +3 -3
- package/components/FSText.vue +1 -1
- package/components/FSWrapGroup.vue +10 -11
- package/components/{FSAutocompleteField.vue → fields/FSAutocompleteField.vue} +26 -19
- package/components/fields/FSColorField.vue +205 -0
- package/components/{FSDateField.vue → fields/FSDateField.vue} +15 -50
- package/components/{FSDateRangeField.vue → fields/FSDateRangeField.vue} +17 -67
- package/components/{FSDateTimeField.vue → fields/FSDateTimeField.vue} +17 -52
- package/components/{FSDateTimeRangeField.vue → fields/FSDateTimeRangeField.vue} +45 -81
- package/components/{FSIconField.vue → fields/FSIconField.vue} +16 -55
- package/components/{FSNumberField.vue → fields/FSNumberField.vue} +17 -27
- package/components/{FSPasswordField.vue → fields/FSPasswordField.vue} +5 -29
- package/components/{FSRichTextField.vue → fields/FSRichTextField.vue} +13 -11
- package/components/{FSSearchField.vue → fields/FSSearchField.vue} +1 -1
- package/components/{FSSelectField.vue → fields/FSSelectField.vue} +17 -21
- package/components/{FSTagField.vue → fields/FSTagField.vue} +18 -53
- package/components/{FSTextArea.vue → fields/FSTextArea.vue} +26 -26
- package/components/{FSTextField.vue → fields/FSTextField.vue} +18 -18
- package/components/fields/FSTimeField.vue +202 -0
- package/components/fields/FSTimeSlotField.vue +269 -0
- package/components/lists/FSDataTableUI.vue +10 -12
- package/components/lists/FSFilterButton.vue +1 -1
- package/components/tiles/FSDeviceOrganisationTileUI.vue +4 -9
- package/components/tiles/FSGroupTileUI.vue +4 -9
- package/composables/index.ts +1 -0
- package/composables/useBreakpoints.ts +7 -5
- package/composables/useRules.ts +72 -0
- package/elements/FSFormElement.ts +17 -0
- package/icons/flags/France.vue +9 -0
- package/icons/flags/Germany.vue +7 -0
- package/icons/flags/GreatBritain.vue +9 -0
- package/icons/flags/Italy.vue +9 -0
- package/icons/flags/Portugal.vue +59 -0
- package/icons/flags/Spain.vue +546 -0
- package/icons/flags/UnitedStates.vue +12 -0
- package/icons/sets.ts +17 -0
- package/models/rules.ts +8 -0
- package/package.json +4 -4
- package/styles/components/fs_autocomplete_field.scss +3 -60
- package/styles/components/fs_clock.scss +4 -0
- package/styles/components/fs_color_field.scss +21 -0
- package/styles/components/fs_data_table.scss +7 -2
- package/styles/components/fs_divider.scss +5 -0
- package/styles/components/fs_image.scss +12 -1
- package/styles/components/fs_label.scss +86 -0
- package/styles/components/fs_pagination.scss +3 -3
- package/styles/components/fs_rich_text_field.scss +1 -1
- package/styles/components/fs_select_field.scss +3 -4
- package/styles/components/fs_switch.scss +4 -4
- package/styles/components/fs_text_area.scss +2 -0
- package/styles/components/fs_text_field.scss +1 -0
- package/styles/components/fs_time_field.scss +16 -0
- package/styles/components/fs_timeslot_field.scss +12 -0
- package/styles/components/index.scss +4 -0
- package/styles/globals/overrides.scss +8 -6
- package/styles/globals/text_fonts.scss +18 -0
- package/utils/color.ts +7 -0
- package/utils/css.ts +2 -1
- package/utils/icons.ts +88 -2
- package/utils/index.ts +3 -1
- package/utils/time.ts +29 -0
- package/components/FSHeaderButton.vue +0 -17
- package/components/lists/FSDataIteratorGroup.vue +0 -7
|
@@ -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
|
-
:
|
|
46
|
-
:
|
|
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 "
|
|
75
|
-
import FSCol from "
|
|
76
|
-
import FSRow from "
|
|
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,6 +142,7 @@ export default defineComponent({
|
|
|
140
142
|
},
|
|
141
143
|
emits: ["update:modelValue"],
|
|
142
144
|
setup(props) {
|
|
145
|
+
const { validateOn, blurred, getMessages } = useRules();
|
|
143
146
|
const { getColors } = useColors();
|
|
144
147
|
const { slots } = useSlots();
|
|
145
148
|
|
|
@@ -169,19 +172,12 @@ export default defineComponent({
|
|
|
169
172
|
};
|
|
170
173
|
});
|
|
171
174
|
|
|
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
|
-
});
|
|
175
|
+
const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
|
|
182
176
|
|
|
183
177
|
return {
|
|
178
|
+
validateOn,
|
|
184
179
|
messages,
|
|
180
|
+
blurred,
|
|
185
181
|
slots,
|
|
186
182
|
style
|
|
187
183
|
};
|
|
@@ -6,44 +6,15 @@
|
|
|
6
6
|
:hideHeader="$props.hideHeader"
|
|
7
7
|
:required="$props.required"
|
|
8
8
|
:editable="$props.editable"
|
|
9
|
-
:
|
|
9
|
+
:rules="$props.rules"
|
|
10
|
+
:messages="messages"
|
|
11
|
+
:validateOn="validateOn"
|
|
12
|
+
:validationValue="$props.modelValue"
|
|
10
13
|
@keydown.enter="onAdd"
|
|
14
|
+
@blur="blurred = true"
|
|
11
15
|
v-model="innerValue"
|
|
12
16
|
v-bind="$attrs"
|
|
13
17
|
>
|
|
14
|
-
<template v-if="!$props.hideHeader" #label>
|
|
15
|
-
<slot name="label">
|
|
16
|
-
<FSRow :wrap="false">
|
|
17
|
-
<FSSpan
|
|
18
|
-
v-if="$props.label"
|
|
19
|
-
class="fs-tag-field-label"
|
|
20
|
-
font="text-overline"
|
|
21
|
-
:style="style"
|
|
22
|
-
>
|
|
23
|
-
{{ $props.label }}
|
|
24
|
-
</FSSpan>
|
|
25
|
-
<FSSpan
|
|
26
|
-
v-if="$props.label && $props.required"
|
|
27
|
-
class="fs-tag-field-label"
|
|
28
|
-
style="margin-left: -8px;"
|
|
29
|
-
font="text-overline"
|
|
30
|
-
:ellipsis="false"
|
|
31
|
-
:style="style"
|
|
32
|
-
>
|
|
33
|
-
*
|
|
34
|
-
</FSSpan>
|
|
35
|
-
<v-spacer style="min-width: 40px;" />
|
|
36
|
-
<FSSpan
|
|
37
|
-
v-if="messages.length > 0"
|
|
38
|
-
class="fs-tag-field-messages"
|
|
39
|
-
font="text-overline"
|
|
40
|
-
:style="style"
|
|
41
|
-
>
|
|
42
|
-
{{ messages.join(", ") }}
|
|
43
|
-
</FSSpan>
|
|
44
|
-
</FSRow>
|
|
45
|
-
</slot>
|
|
46
|
-
</template>
|
|
47
18
|
<template #append-inner>
|
|
48
19
|
<slot name="append-inner">
|
|
49
20
|
<FSButton
|
|
@@ -73,14 +44,14 @@
|
|
|
73
44
|
import { computed, defineComponent, PropType, ref } from "vue";
|
|
74
45
|
|
|
75
46
|
import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
76
|
-
import { useColors } from "@dative-gpi/foundation-shared-components/composables";
|
|
47
|
+
import { useColors, useRules } from "@dative-gpi/foundation-shared-components/composables";
|
|
77
48
|
|
|
78
49
|
import FSTextField from "./FSTextField.vue";
|
|
79
|
-
import FSTagGroup from "
|
|
80
|
-
import FSButton from "
|
|
81
|
-
import FSSpan from "
|
|
82
|
-
import FSCol from "
|
|
83
|
-
import FSRow from "
|
|
50
|
+
import FSTagGroup from "../FSTagGroup.vue";
|
|
51
|
+
import FSButton from "../FSButton.vue";
|
|
52
|
+
import FSSpan from "../FSSpan.vue";
|
|
53
|
+
import FSCol from "../FSCol.vue";
|
|
54
|
+
import FSRow from "../FSRow.vue";
|
|
84
55
|
|
|
85
56
|
export default defineComponent({
|
|
86
57
|
name: "FSTagField",
|
|
@@ -141,6 +112,7 @@ export default defineComponent({
|
|
|
141
112
|
},
|
|
142
113
|
emits: ["update:modelValue"],
|
|
143
114
|
setup(props, { emit }) {
|
|
115
|
+
const {validateOn, blurred, getMessages} = useRules();
|
|
144
116
|
const { getColors } = useColors();
|
|
145
117
|
|
|
146
118
|
const errors = getColors(ColorEnum.Error);
|
|
@@ -161,16 +133,7 @@ export default defineComponent({
|
|
|
161
133
|
};
|
|
162
134
|
});
|
|
163
135
|
|
|
164
|
-
const messages = computed((): string[] =>
|
|
165
|
-
const messages = [];
|
|
166
|
-
for (const rule of props.rules) {
|
|
167
|
-
const message = rule(props.modelValue);
|
|
168
|
-
if (typeof(message) === "string") {
|
|
169
|
-
messages.push(message);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return messages;
|
|
173
|
-
});
|
|
136
|
+
const messages = computed((): string[] => getMessages(props.modelValue, props.rules));
|
|
174
137
|
|
|
175
138
|
const onAdd = (): void => {
|
|
176
139
|
if (!props.editable) {
|
|
@@ -196,12 +159,14 @@ export default defineComponent({
|
|
|
196
159
|
}
|
|
197
160
|
|
|
198
161
|
return {
|
|
199
|
-
ColorEnum,
|
|
200
162
|
innerValue,
|
|
163
|
+
validateOn,
|
|
164
|
+
ColorEnum,
|
|
201
165
|
messages,
|
|
166
|
+
blurred,
|
|
202
167
|
style,
|
|
203
|
-
|
|
204
|
-
|
|
168
|
+
onRemove,
|
|
169
|
+
onAdd
|
|
205
170
|
};
|
|
206
171
|
}
|
|
207
172
|
});
|
|
@@ -36,17 +36,19 @@
|
|
|
36
36
|
<v-textarea
|
|
37
37
|
clearIcon="mdi-close"
|
|
38
38
|
variant="outlined"
|
|
39
|
-
hide-details
|
|
40
39
|
:style="style"
|
|
41
40
|
:class="classes"
|
|
42
41
|
:rows="$props.rows"
|
|
43
|
-
:
|
|
42
|
+
:hideDetails="true"
|
|
44
43
|
:noResize="!$props.resize"
|
|
45
44
|
:autoGrow="$props.autoGrow"
|
|
46
45
|
:readonly="!$props.editable"
|
|
47
|
-
:clearable="$props.editable"
|
|
46
|
+
:clearable="$props.editable && !!$props.modelValue"
|
|
47
|
+
:rules="$props.rules"
|
|
48
|
+
:validateOn="validateOn"
|
|
48
49
|
:modelValue="$props.modelValue"
|
|
49
50
|
@update:modelValue="(value) => $emit('update:modelValue', value)"
|
|
51
|
+
@blur="blurred = true"
|
|
50
52
|
v-bind="$attrs"
|
|
51
53
|
>
|
|
52
54
|
<template v-for="(_, name) in $slots" v-slot:[name]="slotData">
|
|
@@ -69,12 +71,12 @@
|
|
|
69
71
|
<script lang="ts">
|
|
70
72
|
import { computed, defineComponent, PropType } from "vue";
|
|
71
73
|
|
|
72
|
-
import { useColors, useBreakpoints } from "@dative-gpi/foundation-shared-components/composables";
|
|
74
|
+
import { useColors, useBreakpoints, useRules } from "@dative-gpi/foundation-shared-components/composables";
|
|
73
75
|
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
74
76
|
|
|
75
|
-
import FSSpan from "
|
|
76
|
-
import FSCol from "
|
|
77
|
-
import FSRow from "
|
|
77
|
+
import FSSpan from "../FSSpan.vue";
|
|
78
|
+
import FSCol from "../FSCol.vue";
|
|
79
|
+
import FSRow from "../FSRow.vue";
|
|
78
80
|
|
|
79
81
|
export default defineComponent({
|
|
80
82
|
name: "FSTextArea",
|
|
@@ -83,7 +85,6 @@ export default defineComponent({
|
|
|
83
85
|
FSCol,
|
|
84
86
|
FSRow
|
|
85
87
|
},
|
|
86
|
-
inheritAttrs: false,
|
|
87
88
|
props: {
|
|
88
89
|
label: {
|
|
89
90
|
type: String,
|
|
@@ -100,11 +101,6 @@ export default defineComponent({
|
|
|
100
101
|
required: false,
|
|
101
102
|
default: null
|
|
102
103
|
},
|
|
103
|
-
required: {
|
|
104
|
-
type: Boolean,
|
|
105
|
-
required: false,
|
|
106
|
-
default: false
|
|
107
|
-
},
|
|
108
104
|
rows: {
|
|
109
105
|
type: Number,
|
|
110
106
|
required: false,
|
|
@@ -113,23 +109,33 @@ export default defineComponent({
|
|
|
113
109
|
resize: {
|
|
114
110
|
type: Boolean,
|
|
115
111
|
required: false,
|
|
116
|
-
default:
|
|
112
|
+
default: false
|
|
117
113
|
},
|
|
118
114
|
autoGrow: {
|
|
119
115
|
type: Boolean,
|
|
120
116
|
required: false,
|
|
121
|
-
default:
|
|
117
|
+
default: true
|
|
122
118
|
},
|
|
123
119
|
hideHeader: {
|
|
124
120
|
type: Boolean,
|
|
125
121
|
required: false,
|
|
126
122
|
default: false
|
|
127
123
|
},
|
|
124
|
+
required: {
|
|
125
|
+
type: Boolean,
|
|
126
|
+
required: false,
|
|
127
|
+
default: false
|
|
128
|
+
},
|
|
128
129
|
rules: {
|
|
129
130
|
type: Array as PropType<Function[]>,
|
|
130
131
|
required: false,
|
|
131
132
|
default: () => []
|
|
132
133
|
},
|
|
134
|
+
messages: {
|
|
135
|
+
type: Array as PropType<string[]>,
|
|
136
|
+
required: false,
|
|
137
|
+
default: null
|
|
138
|
+
},
|
|
133
139
|
editable: {
|
|
134
140
|
type: Boolean,
|
|
135
141
|
required: false,
|
|
@@ -138,6 +144,7 @@ export default defineComponent({
|
|
|
138
144
|
},
|
|
139
145
|
emits: ["update:modelValue"],
|
|
140
146
|
setup(props) {
|
|
147
|
+
const { validateOn, blurred, getMessages } = useRules();
|
|
141
148
|
const { isMobileSized } = useBreakpoints();
|
|
142
149
|
const { getColors } = useColors();
|
|
143
150
|
|
|
@@ -181,17 +188,6 @@ export default defineComponent({
|
|
|
181
188
|
};
|
|
182
189
|
});
|
|
183
190
|
|
|
184
|
-
const messages = computed(() => {
|
|
185
|
-
const messages = [];
|
|
186
|
-
for (const rule of props.rules) {
|
|
187
|
-
const message = rule(props.modelValue);
|
|
188
|
-
if (typeof(message) === "string") {
|
|
189
|
-
messages.push(message);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return messages;
|
|
193
|
-
});
|
|
194
|
-
|
|
195
191
|
const classes = computed((): string[] => {
|
|
196
192
|
const classNames = ["fs-text-area"];
|
|
197
193
|
if (props.autoGrow) {
|
|
@@ -200,8 +196,12 @@ export default defineComponent({
|
|
|
200
196
|
return classNames;
|
|
201
197
|
});
|
|
202
198
|
|
|
199
|
+
const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
|
|
200
|
+
|
|
203
201
|
return {
|
|
202
|
+
validateOn,
|
|
204
203
|
messages,
|
|
204
|
+
blurred,
|
|
205
205
|
style,
|
|
206
206
|
classes
|
|
207
207
|
};
|
|
@@ -35,14 +35,16 @@
|
|
|
35
35
|
class="fs-text-field"
|
|
36
36
|
clearIcon="mdi-close"
|
|
37
37
|
variant="outlined"
|
|
38
|
-
hide-details
|
|
39
38
|
:style="style"
|
|
40
39
|
:type="$props.type"
|
|
41
|
-
:
|
|
40
|
+
:hideDetails="true"
|
|
42
41
|
:readonly="!$props.editable"
|
|
43
|
-
:clearable="$props.editable"
|
|
42
|
+
:clearable="$props.editable && !!$props.modelValue"
|
|
43
|
+
:rules="$props.rules"
|
|
44
|
+
:validateOn="validateOn"
|
|
44
45
|
:modelValue="$props.modelValue"
|
|
45
46
|
@update:modelValue="(value) => $emit('update:modelValue', value)"
|
|
47
|
+
@blur="blurred = true"
|
|
46
48
|
v-bind="$attrs"
|
|
47
49
|
>
|
|
48
50
|
<template v-for="(_, name) in slots" v-slot:[name]="slotData">
|
|
@@ -65,12 +67,12 @@
|
|
|
65
67
|
<script lang="ts">
|
|
66
68
|
import { computed, defineComponent, PropType } from "vue";
|
|
67
69
|
|
|
68
|
-
import { useColors, useSlots } from "@dative-gpi/foundation-shared-components/composables";
|
|
70
|
+
import { useColors, useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
|
|
69
71
|
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
70
72
|
|
|
71
|
-
import FSSpan from "
|
|
72
|
-
import FSCol from "
|
|
73
|
-
import FSRow from "
|
|
73
|
+
import FSSpan from "../FSSpan.vue";
|
|
74
|
+
import FSCol from "../FSCol.vue";
|
|
75
|
+
import FSRow from "../FSRow.vue";
|
|
74
76
|
|
|
75
77
|
export default defineComponent({
|
|
76
78
|
name: "FSTextField",
|
|
@@ -79,7 +81,6 @@ export default defineComponent({
|
|
|
79
81
|
FSCol,
|
|
80
82
|
FSRow
|
|
81
83
|
},
|
|
82
|
-
inheritAttrs: false,
|
|
83
84
|
props: {
|
|
84
85
|
label: {
|
|
85
86
|
type: String,
|
|
@@ -116,6 +117,11 @@ export default defineComponent({
|
|
|
116
117
|
required: false,
|
|
117
118
|
default: () => []
|
|
118
119
|
},
|
|
120
|
+
messages: {
|
|
121
|
+
type: Array as PropType<string[]>,
|
|
122
|
+
required: false,
|
|
123
|
+
default: null
|
|
124
|
+
},
|
|
119
125
|
editable: {
|
|
120
126
|
type: Boolean,
|
|
121
127
|
required: false,
|
|
@@ -124,6 +130,7 @@ export default defineComponent({
|
|
|
124
130
|
},
|
|
125
131
|
emits: ["update:modelValue"],
|
|
126
132
|
setup(props) {
|
|
133
|
+
const { validateOn, blurred, getMessages } = useRules();
|
|
127
134
|
const { getColors } = useColors();
|
|
128
135
|
const { slots } = useSlots();
|
|
129
136
|
|
|
@@ -153,19 +160,12 @@ export default defineComponent({
|
|
|
153
160
|
};
|
|
154
161
|
});
|
|
155
162
|
|
|
156
|
-
const messages = computed((): string[] =>
|
|
157
|
-
const messages = [];
|
|
158
|
-
for (const rule of props.rules) {
|
|
159
|
-
const message = rule(props.modelValue ?? "");
|
|
160
|
-
if (typeof(message) === "string") {
|
|
161
|
-
messages.push(message);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return messages;
|
|
165
|
-
});
|
|
163
|
+
const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
|
|
166
164
|
|
|
167
165
|
return {
|
|
166
|
+
validateOn,
|
|
168
167
|
messages,
|
|
168
|
+
blurred,
|
|
169
169
|
slots,
|
|
170
170
|
style
|
|
171
171
|
};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FSCol>
|
|
3
|
+
<slot v-if="!$props.hideHeader" name="label">
|
|
4
|
+
<FSRow :wrap="false">
|
|
5
|
+
<FSSpan
|
|
6
|
+
v-if="$props.label"
|
|
7
|
+
class="fs-time-field-label"
|
|
8
|
+
font="text-overline"
|
|
9
|
+
:style="style"
|
|
10
|
+
>
|
|
11
|
+
{{ $props.label }}
|
|
12
|
+
</FSSpan>
|
|
13
|
+
<FSSpan
|
|
14
|
+
v-if="$props.label && $props.required"
|
|
15
|
+
class="fs-time-field-label"
|
|
16
|
+
style="margin-left: -8px;"
|
|
17
|
+
font="text-overline"
|
|
18
|
+
:ellipsis="false"
|
|
19
|
+
:style="style"
|
|
20
|
+
>
|
|
21
|
+
*
|
|
22
|
+
</FSSpan>
|
|
23
|
+
<v-spacer style="min-width: 40px;" />
|
|
24
|
+
<FSSpan
|
|
25
|
+
v-if="messages.length > 0"
|
|
26
|
+
class="fs-time-field-messages"
|
|
27
|
+
font="text-overline"
|
|
28
|
+
:style="style"
|
|
29
|
+
>
|
|
30
|
+
{{ messages.join(", ") }}
|
|
31
|
+
</FSSpan>
|
|
32
|
+
</FSRow>
|
|
33
|
+
</slot>
|
|
34
|
+
<FSRow>
|
|
35
|
+
<FSNumberField
|
|
36
|
+
:editable="$props.editable"
|
|
37
|
+
:hideHeader="true"
|
|
38
|
+
:rules="$props.rules"
|
|
39
|
+
:messages="messages"
|
|
40
|
+
:validateOn="validateOn"
|
|
41
|
+
:validationValue="$props.modelValue"
|
|
42
|
+
:modelValue="innerTime"
|
|
43
|
+
@update:modelValue="onSubmitValue"
|
|
44
|
+
v-bind="$attrs"
|
|
45
|
+
>
|
|
46
|
+
<template v-for="(_, name) in slots" v-slot:[name]="slotData">
|
|
47
|
+
<slot :name="name" v-bind="slotData" />
|
|
48
|
+
</template>
|
|
49
|
+
</FSNumberField>
|
|
50
|
+
<FSSelectField
|
|
51
|
+
class="fs-time-field-select"
|
|
52
|
+
:editable="$props.editable"
|
|
53
|
+
:hideHeader="true"
|
|
54
|
+
:clearable="false"
|
|
55
|
+
:items="timeScale"
|
|
56
|
+
:modelValue="selectedUnit.id"
|
|
57
|
+
@update:modelValue="onSubmitTimeScale"
|
|
58
|
+
/>
|
|
59
|
+
</FSRow>
|
|
60
|
+
<slot name="description">
|
|
61
|
+
<FSSpan
|
|
62
|
+
v-if="$props.description"
|
|
63
|
+
class="fs-time-field-description"
|
|
64
|
+
font="text-underline"
|
|
65
|
+
:style="style"
|
|
66
|
+
>
|
|
67
|
+
{{ $props.description }}
|
|
68
|
+
</FSSpan>
|
|
69
|
+
</slot>
|
|
70
|
+
</FSCol>
|
|
71
|
+
</template>
|
|
72
|
+
|
|
73
|
+
<script lang="ts">
|
|
74
|
+
import { computed, defineComponent, PropType, ref } from "vue";
|
|
75
|
+
|
|
76
|
+
import { getTimeScaleIndex, timeScale } from "@dative-gpi/foundation-shared-components/utils";
|
|
77
|
+
import { useColors, useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
|
|
78
|
+
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
79
|
+
|
|
80
|
+
import FSNumberField from "./FSNumberField.vue";
|
|
81
|
+
import FSSelectField from "./FSSelectField.vue";
|
|
82
|
+
import FSSpan from "../FSSpan.vue";
|
|
83
|
+
import FSCol from "../FSCol.vue";
|
|
84
|
+
import FSRow from "../FSRow.vue";
|
|
85
|
+
|
|
86
|
+
export default defineComponent({
|
|
87
|
+
name: "FSTimeField",
|
|
88
|
+
components: {
|
|
89
|
+
FSNumberField,
|
|
90
|
+
FSSelectField,
|
|
91
|
+
FSSpan,
|
|
92
|
+
FSCol,
|
|
93
|
+
FSRow
|
|
94
|
+
},
|
|
95
|
+
props: {
|
|
96
|
+
label: {
|
|
97
|
+
type: String,
|
|
98
|
+
required: false,
|
|
99
|
+
default: null
|
|
100
|
+
},
|
|
101
|
+
description: {
|
|
102
|
+
type: String,
|
|
103
|
+
required: false,
|
|
104
|
+
default: null
|
|
105
|
+
},
|
|
106
|
+
modelValue: {
|
|
107
|
+
type: Number,
|
|
108
|
+
required: false,
|
|
109
|
+
default: null
|
|
110
|
+
},
|
|
111
|
+
hideHeader: {
|
|
112
|
+
type: Boolean,
|
|
113
|
+
required: false,
|
|
114
|
+
default: false
|
|
115
|
+
},
|
|
116
|
+
required: {
|
|
117
|
+
type: Boolean,
|
|
118
|
+
required: false,
|
|
119
|
+
default: false
|
|
120
|
+
},
|
|
121
|
+
rules: {
|
|
122
|
+
type: Array as PropType<Function[]>,
|
|
123
|
+
required: false,
|
|
124
|
+
default: () => []
|
|
125
|
+
},
|
|
126
|
+
messages: {
|
|
127
|
+
type: Array as PropType<string[]>,
|
|
128
|
+
required: false,
|
|
129
|
+
default: null
|
|
130
|
+
},
|
|
131
|
+
editable: {
|
|
132
|
+
type: Boolean,
|
|
133
|
+
required: false,
|
|
134
|
+
default: true
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
emits: ["update:modelValue"],
|
|
138
|
+
setup(props, { emit }) {
|
|
139
|
+
const { validateOn, blurred, getMessages } = useRules();
|
|
140
|
+
const { getColors } = useColors();
|
|
141
|
+
const { slots } = useSlots();
|
|
142
|
+
|
|
143
|
+
delete slots.label;
|
|
144
|
+
delete slots.description;
|
|
145
|
+
|
|
146
|
+
const errors = getColors(ColorEnum.Error);
|
|
147
|
+
const lights = getColors(ColorEnum.Light);
|
|
148
|
+
const darks = getColors(ColorEnum.Dark);
|
|
149
|
+
|
|
150
|
+
const innerTime = ref(props.modelValue);
|
|
151
|
+
const selectedUnit = ref(timeScale[0]);
|
|
152
|
+
|
|
153
|
+
if (getTimeScaleIndex(props.modelValue) !== 0) {
|
|
154
|
+
selectedUnit.value = timeScale[getTimeScaleIndex(props.modelValue)];
|
|
155
|
+
innerTime.value = props.modelValue / selectedUnit.value.id;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const style = computed((): {[code: string]: string} & Partial<CSSStyleDeclaration> => {
|
|
159
|
+
if (!props.editable) {
|
|
160
|
+
return {
|
|
161
|
+
"--fs-time-field-cursor" : "default",
|
|
162
|
+
"--fs-time-field-border-color" : lights.base,
|
|
163
|
+
"--fs-time-field-color" : lights.dark,
|
|
164
|
+
"--fs-time-field-active-border-color": lights.base
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
"--fs-time-field-cursor" : "text",
|
|
169
|
+
"--fs-time-field-border-color" : lights.dark,
|
|
170
|
+
"--fs-time-field-color" : darks.base,
|
|
171
|
+
"--fs-time-field-active-border-color": darks.dark,
|
|
172
|
+
"--fs-time-field-error-color" : errors.base,
|
|
173
|
+
"--fs-time-field-error-border-color" : errors.base
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
|
|
178
|
+
|
|
179
|
+
const onSubmitValue = (value: number): void => {
|
|
180
|
+
innerTime.value = value;
|
|
181
|
+
emit("update:modelValue", innerTime.value * selectedUnit.value.id);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const onSubmitTimeScale = (value: number): void => {
|
|
185
|
+
selectedUnit.value = timeScale.find((item) => item.id === value);
|
|
186
|
+
emit("update:modelValue", innerTime.value * selectedUnit.value.id);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
selectedUnit,
|
|
191
|
+
validateOn,
|
|
192
|
+
innerTime,
|
|
193
|
+
timeScale,
|
|
194
|
+
messages,
|
|
195
|
+
blurred,
|
|
196
|
+
style,
|
|
197
|
+
onSubmitTimeScale,
|
|
198
|
+
onSubmitValue
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
</script>
|