@dative-gpi/foundation-shared-components 0.0.25 → 0.0.26
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 +123 -0
- package/components/FSClickable.vue +17 -13
- package/components/FSForm.vue +12 -5
- package/components/fields/FSColorField.vue +3 -2
- 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 +38 -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,123 @@
|
|
|
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
|
+
borderRadius: {
|
|
74
|
+
type: [String, Number],
|
|
75
|
+
required: false,
|
|
76
|
+
default: "4px"
|
|
77
|
+
},
|
|
78
|
+
divider: {
|
|
79
|
+
type: Boolean,
|
|
80
|
+
required: false,
|
|
81
|
+
default: false
|
|
82
|
+
},
|
|
83
|
+
expandIcon: {
|
|
84
|
+
type: String,
|
|
85
|
+
required: false,
|
|
86
|
+
default: "mdi-chevron-down"
|
|
87
|
+
},
|
|
88
|
+
collapseIcon: {
|
|
89
|
+
type: String,
|
|
90
|
+
required: false,
|
|
91
|
+
default: "mdi-chevron-up"
|
|
92
|
+
},
|
|
93
|
+
color: {
|
|
94
|
+
type: String as PropType<ColorBase>,
|
|
95
|
+
required: false,
|
|
96
|
+
default: ColorEnum.Primary
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
setup(props) {
|
|
100
|
+
const { getColors } = useColors();
|
|
101
|
+
|
|
102
|
+
const colors = computed(() => getColors(props.color));
|
|
103
|
+
const backgrounds = getColors(ColorEnum.Background);
|
|
104
|
+
const darks = getColors(ColorEnum.Dark);
|
|
105
|
+
|
|
106
|
+
const style = computed((): {[code: string]: string} & Partial<CSSStyleDeclaration> => {
|
|
107
|
+
return {
|
|
108
|
+
"--fs-accordion-panel-border-radius" : sizeToVar(props.borderRadius),
|
|
109
|
+
"--fs-accordion-panel-border-size" : props.divider ? "1px" : "0",
|
|
110
|
+
"--fs-accordion-panel-border-color" : darks.base,
|
|
111
|
+
"--fs-accordion-panel-background-color" : backgrounds.base,
|
|
112
|
+
"--fs-accordion-panel-color" : darks.base,
|
|
113
|
+
"--fs-accordion-panel-hover-background-color": colors.value.light,
|
|
114
|
+
"--fs-accordion-panel-hover-color" : colors.value.base,
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
style
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
</script>
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<button
|
|
3
3
|
v-if="!href"
|
|
4
|
-
:
|
|
5
|
-
:class="classes"
|
|
6
|
-
:style="style"
|
|
4
|
+
:class="wrapperClasses"
|
|
7
5
|
@click.stop="onClick"
|
|
8
|
-
v-bind="$attrs"
|
|
9
6
|
>
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
<FSCard
|
|
8
|
+
:border="$props.border"
|
|
9
|
+
:class="classes"
|
|
10
|
+
:style="style"
|
|
11
|
+
v-bind="$attrs"
|
|
12
|
+
>
|
|
13
|
+
<template v-for="(_, name) in $slots" v-slot:[name]="slotData">
|
|
14
|
+
<slot :name="name" v-bind="slotData" />
|
|
15
|
+
</template>
|
|
16
|
+
</FSCard>
|
|
17
|
+
</button>
|
|
14
18
|
<a
|
|
15
19
|
v-else
|
|
16
|
-
:class="
|
|
20
|
+
:class="wrapperClasses"
|
|
17
21
|
:href="href"
|
|
18
22
|
>
|
|
19
23
|
<FSCard
|
|
@@ -138,10 +142,10 @@ export default defineComponent({
|
|
|
138
142
|
return classNames;
|
|
139
143
|
});
|
|
140
144
|
|
|
141
|
-
const
|
|
145
|
+
const wrapperClasses = computed((): string[] => {
|
|
142
146
|
const classNames: string[] = [];
|
|
143
147
|
if (props.fullWidth) {
|
|
144
|
-
classNames.push("fs-clickable-
|
|
148
|
+
classNames.push("fs-clickable-wrapper-full-width");
|
|
145
149
|
}
|
|
146
150
|
return classNames;
|
|
147
151
|
});
|
|
@@ -165,7 +169,7 @@ export default defineComponent({
|
|
|
165
169
|
};
|
|
166
170
|
|
|
167
171
|
return {
|
|
168
|
-
|
|
172
|
+
wrapperClasses,
|
|
169
173
|
classes,
|
|
170
174
|
style,
|
|
171
175
|
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
|
});
|
|
@@ -157,12 +157,13 @@ export default defineComponent({
|
|
|
157
157
|
},
|
|
158
158
|
emits: ["update:modelValue", "update:opacity"],
|
|
159
159
|
setup(props, { emit }) {
|
|
160
|
+
const { getColors } = useColors();
|
|
160
161
|
const { slots } = useSlots();
|
|
161
162
|
|
|
162
163
|
delete slots.description;
|
|
163
164
|
|
|
164
|
-
const lights =
|
|
165
|
-
const darks =
|
|
165
|
+
const lights = getColors(ColorEnum.Light);
|
|
166
|
+
const darks = getColors(ColorEnum.Dark);
|
|
166
167
|
|
|
167
168
|
const menu = ref(false);
|
|
168
169
|
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.26",
|
|
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.26",
|
|
14
|
+
"@dative-gpi/foundation-shared-services": "0.0.26",
|
|
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": "58a49a5422156548728d405e3c289ba4e80cbe39"
|
|
36
36
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
.fs-accordion-panel > .v-expansion-panel-title {
|
|
2
|
+
border-radius: var(--fs-accordion-panel-border-radius) !important;
|
|
3
|
+
transition: all 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
|
4
|
+
min-height: 0 !important;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
padding: 12px;
|
|
7
|
+
|
|
8
|
+
background-color: var(--fs-accordion-panel-background-color) !important;
|
|
9
|
+
color: var(--fs-accordion-panel-color) !important;
|
|
10
|
+
|
|
11
|
+
&:hover,
|
|
12
|
+
&--active {
|
|
13
|
+
background-color: var(--fs-accordion-panel-hover-background-color) !important;
|
|
14
|
+
color: var(--fs-accordion-panel-hover-color) !important;
|
|
15
|
+
min-height: 0 !important;
|
|
16
|
+
|
|
17
|
+
& .fs-accordion-panel-title {
|
|
18
|
+
@extend .text-button
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.fs-accordion-panel > .v-expansion-panel-text {
|
|
24
|
+
border-radius: var(--fs-accordion-panel-border-radius) !important;
|
|
25
|
+
transition: all 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
|
26
|
+
padding: 12px;
|
|
27
|
+
|
|
28
|
+
background-color: var(--fs-accordion-panel-background-color) !important;
|
|
29
|
+
color: var(--fs-accordion-panel-color) !important;
|
|
30
|
+
|
|
31
|
+
& > .v-expansion-panel-text__wrapper {
|
|
32
|
+
padding: 0;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.v-expansion-panel:not(:first-child)::after {
|
|
37
|
+
border-top: var(--fs-accordion-panel-border-size) solid var(--fs-accordion-panel-border-color) !important;
|
|
38
|
+
}
|