@dative-gpi/foundation-shared-components 0.0.25 → 0.0.27
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/FSAccordion.vue +27 -0
- package/components/FSAccordionPanel.vue +120 -0
- package/components/FSClickable.vue +24 -14
- package/components/FSForm.vue +12 -5
- package/components/FSToggleSet.vue +3 -3
- package/components/fields/FSColorField.vue +10 -3
- package/components/fields/FSTextField.vue +4 -1
- package/composables/useRules.ts +6 -6
- package/models/rules.ts +1 -0
- package/package.json +4 -4
- package/styles/components/fs_accordion_panel.scss +32 -0
- package/styles/components/fs_clickable.scss +1 -1
- package/styles/components/index.scss +1 -0
- package/styles/globals/overrides.scss +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-expansion-panels variant="accordion">
|
|
3
|
+
<template
|
|
4
|
+
v-for="(component, index) in getChildren()"
|
|
5
|
+
:key="index"
|
|
6
|
+
>
|
|
7
|
+
<component :is="component" />
|
|
8
|
+
</template>
|
|
9
|
+
</v-expansion-panels>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import { defineComponent } from "vue";
|
|
14
|
+
|
|
15
|
+
import { useSlots } from "@dative-gpi/foundation-shared-components/composables";
|
|
16
|
+
|
|
17
|
+
export default defineComponent({
|
|
18
|
+
name: "FSAccordion",
|
|
19
|
+
setup() {
|
|
20
|
+
const { getChildren } = useSlots();
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
getChildren
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
</script>
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-expansion-panel
|
|
3
|
+
class="fs-accordion-panel"
|
|
4
|
+
:collapseIcon="$props.collapseIcon"
|
|
5
|
+
:expandIcon="$props.expandIcon"
|
|
6
|
+
:disabled="false"
|
|
7
|
+
:elevation="0"
|
|
8
|
+
:style="style"
|
|
9
|
+
v-bind="$attrs"
|
|
10
|
+
>
|
|
11
|
+
<template #title>
|
|
12
|
+
<slot name="title">
|
|
13
|
+
<FSRow>
|
|
14
|
+
<FSIcon
|
|
15
|
+
v-if="$props.prependIcon"
|
|
16
|
+
>
|
|
17
|
+
{{ $props.prependIcon }}
|
|
18
|
+
</FSIcon>
|
|
19
|
+
<FSSpan
|
|
20
|
+
class="fs-accordion-panel-title"
|
|
21
|
+
>
|
|
22
|
+
{{ $props.title }}
|
|
23
|
+
</FSSpan>
|
|
24
|
+
</FSRow>
|
|
25
|
+
</slot>
|
|
26
|
+
</template>
|
|
27
|
+
<template #text>
|
|
28
|
+
<slot name="content">
|
|
29
|
+
<FSText>
|
|
30
|
+
{{ $props.content }}
|
|
31
|
+
</FSText>
|
|
32
|
+
</slot>
|
|
33
|
+
</template>
|
|
34
|
+
</v-expansion-panel>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script lang="ts">
|
|
38
|
+
import { computed, defineComponent, PropType } from "vue";
|
|
39
|
+
|
|
40
|
+
import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
41
|
+
import { useColors } from "@dative-gpi/foundation-shared-components/composables";
|
|
42
|
+
import { sizeToVar } from "@dative-gpi/foundation-shared-components/utils";
|
|
43
|
+
|
|
44
|
+
import FSIcon from "./FSIcon.vue";
|
|
45
|
+
import FSSpan from "./FSSpan.vue";
|
|
46
|
+
import FSText from "./FSText.vue";
|
|
47
|
+
import FSRow from "./FSRow.vue";
|
|
48
|
+
|
|
49
|
+
export default defineComponent({
|
|
50
|
+
name: "FSAccordionPanel",
|
|
51
|
+
components: {
|
|
52
|
+
FSIcon,
|
|
53
|
+
FSSpan,
|
|
54
|
+
FSText,
|
|
55
|
+
FSRow
|
|
56
|
+
},
|
|
57
|
+
props: {
|
|
58
|
+
prependIcon: {
|
|
59
|
+
type: String,
|
|
60
|
+
required: false,
|
|
61
|
+
default: null
|
|
62
|
+
},
|
|
63
|
+
title: {
|
|
64
|
+
type: String,
|
|
65
|
+
required: false,
|
|
66
|
+
default: null
|
|
67
|
+
},
|
|
68
|
+
content: {
|
|
69
|
+
type: String,
|
|
70
|
+
required: false,
|
|
71
|
+
default: null
|
|
72
|
+
},
|
|
73
|
+
paddingTitle: {
|
|
74
|
+
type: [String, Number],
|
|
75
|
+
required: false,
|
|
76
|
+
default: "16px"
|
|
77
|
+
},
|
|
78
|
+
paddingContent: {
|
|
79
|
+
type: [String, Number],
|
|
80
|
+
required: false,
|
|
81
|
+
default: "16px"
|
|
82
|
+
},
|
|
83
|
+
divider: {
|
|
84
|
+
type: Boolean,
|
|
85
|
+
required: false,
|
|
86
|
+
default: true
|
|
87
|
+
},
|
|
88
|
+
expandIcon: {
|
|
89
|
+
type: String,
|
|
90
|
+
required: false,
|
|
91
|
+
default: ""
|
|
92
|
+
},
|
|
93
|
+
collapseIcon: {
|
|
94
|
+
type: String,
|
|
95
|
+
required: false,
|
|
96
|
+
default: ""
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
setup(props) {
|
|
100
|
+
const { getColors } = useColors();
|
|
101
|
+
|
|
102
|
+
const backgrounds = getColors(ColorEnum.Background);
|
|
103
|
+
const lights = getColors(ColorEnum.Light);
|
|
104
|
+
|
|
105
|
+
const style = computed((): {[code: string]: string} & Partial<CSSStyleDeclaration> => {
|
|
106
|
+
return {
|
|
107
|
+
"--fs-accordion-panel-padding-title" : sizeToVar(props.paddingTitle),
|
|
108
|
+
"--fs-accordion-panel-padding-content" : sizeToVar(props.paddingContent),
|
|
109
|
+
"--fs-accordion-panel-divider-size" : props.divider ? "1px" : "0",
|
|
110
|
+
"--fs-accordion-panel-divider-color" : lights.dark,
|
|
111
|
+
"--fs-accordion-panel-background-color" : backgrounds.base
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
style
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
</script>
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<button
|
|
3
3
|
v-if="!href"
|
|
4
|
-
:
|
|
5
|
-
:
|
|
6
|
-
:style="style"
|
|
4
|
+
:class="wrapperClasses"
|
|
5
|
+
:type="$props.type"
|
|
7
6
|
@click.stop="onClick"
|
|
8
|
-
v-bind="$attrs"
|
|
9
7
|
>
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
<FSCard
|
|
9
|
+
:border="$props.border"
|
|
10
|
+
:class="classes"
|
|
11
|
+
:style="style"
|
|
12
|
+
v-bind="$attrs"
|
|
13
|
+
>
|
|
14
|
+
<template v-for="(_, name) in $slots" v-slot:[name]="slotData">
|
|
15
|
+
<slot :name="name" v-bind="slotData" />
|
|
16
|
+
</template>
|
|
17
|
+
</FSCard>
|
|
18
|
+
</button>
|
|
14
19
|
<a
|
|
15
20
|
v-else
|
|
16
|
-
:class="
|
|
21
|
+
:class="wrapperClasses"
|
|
17
22
|
:href="href"
|
|
18
23
|
>
|
|
19
24
|
<FSCard
|
|
@@ -65,10 +70,15 @@ export default defineComponent({
|
|
|
65
70
|
required: false,
|
|
66
71
|
default: "standard"
|
|
67
72
|
},
|
|
73
|
+
type: {
|
|
74
|
+
type: String as PropType<"button" | "submit">,
|
|
75
|
+
required: false,
|
|
76
|
+
default: "submit"
|
|
77
|
+
},
|
|
68
78
|
color: {
|
|
69
79
|
type: String as PropType<ColorBase>,
|
|
70
80
|
required: false,
|
|
71
|
-
default: ColorEnum.
|
|
81
|
+
default: ColorEnum.Light
|
|
72
82
|
},
|
|
73
83
|
fullWidth: {
|
|
74
84
|
type: Boolean,
|
|
@@ -138,10 +148,10 @@ export default defineComponent({
|
|
|
138
148
|
return classNames;
|
|
139
149
|
});
|
|
140
150
|
|
|
141
|
-
const
|
|
151
|
+
const wrapperClasses = computed((): string[] => {
|
|
142
152
|
const classNames: string[] = [];
|
|
143
153
|
if (props.fullWidth) {
|
|
144
|
-
classNames.push("fs-clickable-
|
|
154
|
+
classNames.push("fs-clickable-wrapper-full-width");
|
|
145
155
|
}
|
|
146
156
|
return classNames;
|
|
147
157
|
});
|
|
@@ -165,7 +175,7 @@ export default defineComponent({
|
|
|
165
175
|
};
|
|
166
176
|
|
|
167
177
|
return {
|
|
168
|
-
|
|
178
|
+
wrapperClasses,
|
|
169
179
|
classes,
|
|
170
180
|
style,
|
|
171
181
|
href,
|
package/components/FSForm.vue
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<v-form
|
|
3
3
|
ref="formRef"
|
|
4
4
|
:validateOn="validateOn"
|
|
5
|
-
@submit="
|
|
5
|
+
@submit.stop="onSubmit"
|
|
6
6
|
@update:modelValue="$emit('update:modelValue', $event)"
|
|
7
7
|
>
|
|
8
8
|
<slot />
|
|
@@ -39,13 +39,20 @@ export default defineComponent({
|
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const onSubmit = (event: SubmitEvent) => {
|
|
43
|
+
event.stopImmediatePropagation();
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
submitted.value = true;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
provide("validateOn", validateOn);
|
|
49
|
+
provide("submitted", submitted);
|
|
44
50
|
|
|
45
51
|
return {
|
|
46
|
-
formRef,
|
|
47
52
|
validateOn,
|
|
48
|
-
submitted
|
|
53
|
+
submitted,
|
|
54
|
+
formRef,
|
|
55
|
+
onSubmit
|
|
49
56
|
};
|
|
50
57
|
}
|
|
51
58
|
});
|
|
@@ -148,12 +148,12 @@ export default defineComponent({
|
|
|
148
148
|
padding: {
|
|
149
149
|
type: [String, Number],
|
|
150
150
|
required: false,
|
|
151
|
-
default: 0
|
|
151
|
+
default: "0"
|
|
152
152
|
},
|
|
153
153
|
gap: {
|
|
154
|
-
type: Number,
|
|
154
|
+
type: [String, Number],
|
|
155
155
|
required: false,
|
|
156
|
-
default:
|
|
156
|
+
default: "8px"
|
|
157
157
|
},
|
|
158
158
|
multiple: {
|
|
159
159
|
type: Boolean,
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
</template>
|
|
39
39
|
</FSTextField>
|
|
40
40
|
<FSTextField
|
|
41
|
+
v-if="$props.allowOpacity"
|
|
41
42
|
class="fs-color-field-opacity"
|
|
42
43
|
:label="$tr('ui.color-field.opacity', 'Opacity')"
|
|
43
44
|
:hideHeader="$props.hideHeader"
|
|
@@ -90,7 +91,7 @@
|
|
|
90
91
|
class="fs-color-field-picker"
|
|
91
92
|
mode="hexa"
|
|
92
93
|
:elevation="0"
|
|
93
|
-
:modes="['hexa', 'rgba']"
|
|
94
|
+
:modes="allowOpacity ? ['hexa', 'rgba'] : ['hex', 'rgb']"
|
|
94
95
|
:modelValue="fullColor"
|
|
95
96
|
@update:modelValue="onSubmit"
|
|
96
97
|
/>
|
|
@@ -153,16 +154,22 @@ export default defineComponent({
|
|
|
153
154
|
type: Boolean,
|
|
154
155
|
required: false,
|
|
155
156
|
default: true
|
|
157
|
+
},
|
|
158
|
+
allowOpacity: {
|
|
159
|
+
type: Boolean,
|
|
160
|
+
required: false,
|
|
161
|
+
default: true
|
|
156
162
|
}
|
|
157
163
|
},
|
|
158
164
|
emits: ["update:modelValue", "update:opacity"],
|
|
159
165
|
setup(props, { emit }) {
|
|
166
|
+
const { getColors } = useColors();
|
|
160
167
|
const { slots } = useSlots();
|
|
161
168
|
|
|
162
169
|
delete slots.description;
|
|
163
170
|
|
|
164
|
-
const lights =
|
|
165
|
-
const darks =
|
|
171
|
+
const lights = getColors(ColorEnum.Light);
|
|
172
|
+
const darks = getColors(ColorEnum.Dark);
|
|
166
173
|
|
|
167
174
|
const menu = ref(false);
|
|
168
175
|
const innerColor = ref(props.modelValue.toString().substring(0, 7));
|
package/composables/useRules.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { computed, inject, ref } from "vue";
|
|
1
|
+
import { Ref, computed, inject, ref } from "vue";
|
|
2
2
|
|
|
3
3
|
export const useRules = () => {
|
|
4
|
-
const innerValidateOn = inject<"submit" | "blur" | "input"
|
|
5
|
-
const submitted = inject<boolean
|
|
4
|
+
const innerValidateOn = inject<Ref<"submit" | "blur" | "input">>("validateOn", ref('input'));
|
|
5
|
+
const submitted = inject<Ref<boolean>>("submitted", ref(false));
|
|
6
6
|
|
|
7
7
|
const blurred = ref(false);
|
|
8
8
|
|
|
9
9
|
const validateOn = computed((): string => {
|
|
10
|
-
switch (innerValidateOn) {
|
|
11
|
-
case "submit": return submitted ? "input" : "submit";
|
|
10
|
+
switch (innerValidateOn.value) {
|
|
11
|
+
case "submit": return submitted.value ? "input" : "submit";
|
|
12
12
|
case "blur": return blurred.value ? "input" : "blur";
|
|
13
13
|
case "input": return "input";
|
|
14
14
|
}
|
|
@@ -20,7 +20,7 @@ export const useRules = () => {
|
|
|
20
20
|
}
|
|
21
21
|
switch (validateOn.value) {
|
|
22
22
|
case "submit":
|
|
23
|
-
if (!submitted) {
|
|
23
|
+
if (!submitted.value) {
|
|
24
24
|
return [];
|
|
25
25
|
}
|
|
26
26
|
break;
|
package/models/rules.ts
CHANGED
|
@@ -8,6 +8,7 @@ const { $tr } = useTranslationsProvider();
|
|
|
8
8
|
|
|
9
9
|
export const TextRules = {
|
|
10
10
|
required: (message: string) => (value: string) => !!value || (message ?? $tr("ui.rules.required", "Required")),
|
|
11
|
+
copy: (original: string, message: string) => (value: string) => value === original || (message ?? $tr("ui.rules.copy", "Different from original")),
|
|
11
12
|
min: (min: number, message: string) => (value: string) => value.length >= min || (message ?? $tr("ui.rules.text-min", "Must be at least {0} characters", min.toString())),
|
|
12
13
|
max: (max: number, message: string) => (value: string) => value.length <= max || (message ?? $tr("ui.rules.text-max", "Must be at most {0} characters", max.toString())),
|
|
13
14
|
email: (message: string) => (value: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || (message ?? $tr("ui.rules.text-email", "Must be a valid email")),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dative-gpi/foundation-shared-components",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.27",
|
|
5
5
|
"description": "",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"author": "",
|
|
11
11
|
"license": "ISC",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@dative-gpi/foundation-shared-domain": "0.0.
|
|
14
|
-
"@dative-gpi/foundation-shared-services": "0.0.
|
|
13
|
+
"@dative-gpi/foundation-shared-domain": "0.0.27",
|
|
14
|
+
"@dative-gpi/foundation-shared-services": "0.0.27",
|
|
15
15
|
"@fontsource/montserrat": "^5.0.16",
|
|
16
16
|
"@lexical/clipboard": "^0.12.5",
|
|
17
17
|
"@lexical/history": "^0.12.5",
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
"sass": "^1.69.5",
|
|
33
33
|
"sass-loader": "^13.3.2"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "b46c226b198f482eee4ca6e63ef2923522bf6e8c"
|
|
36
36
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
.fs-accordion-panel > .v-expansion-panel-title {
|
|
2
|
+
background-color: var(--fs-accordion-panel-background-color) !important;
|
|
3
|
+
padding: var(--fs-accordion-panel-padding-title);
|
|
4
|
+
min-height: 0 !important;
|
|
5
|
+
|
|
6
|
+
&:hover,
|
|
7
|
+
&--active {
|
|
8
|
+
background-color: var(--fs-accordion-panel-background-color) !important;
|
|
9
|
+
|
|
10
|
+
& .fs-accordion-panel-title {
|
|
11
|
+
@extend .text-button
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
& > .v-expansion-panel-title__overlay {
|
|
16
|
+
display: none !important;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.fs-accordion-panel > .v-expansion-panel-text {
|
|
21
|
+
background-color: var(--fs-accordion-panel-background-color) !important;
|
|
22
|
+
padding: 0px;
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
& > .v-expansion-panel-text__wrapper {
|
|
26
|
+
padding: var(--fs-accordion-panel-padding-content);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.v-expansion-panel:not(:first-child)::after {
|
|
31
|
+
border-top: var(--fs-accordion-panel-divider-size) solid var(--fs-accordion-panel-divider-color) !important;
|
|
32
|
+
}
|