@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.
@@ -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
- <FSCard
2
+ <button
3
3
  v-if="!href"
4
- :border="$props.border"
5
- :class="classes"
6
- :style="style"
4
+ :class="wrapperClasses"
7
5
  @click.stop="onClick"
8
- v-bind="$attrs"
9
6
  >
10
- <template v-for="(_, name) in $slots" v-slot:[name]="slotData">
11
- <slot :name="name" v-bind="slotData" />
12
- </template>
13
- </FSCard>
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="anchorClasses"
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 anchorClasses = computed((): string[] => {
145
+ const wrapperClasses = computed((): string[] => {
142
146
  const classNames: string[] = [];
143
147
  if (props.fullWidth) {
144
- classNames.push("fs-clickable-anchor-full-width");
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
- anchorClasses,
172
+ wrapperClasses,
169
173
  classes,
170
174
  style,
171
175
  href,
@@ -2,7 +2,7 @@
2
2
  <v-form
3
3
  ref="formRef"
4
4
  :validateOn="validateOn"
5
- @submit="submitted = true"
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
- provide("validateOn", validateOn.value);
43
- provide("submitted", submitted.value);
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 = useColors().getColors(ColorEnum.Light);
165
- const darks = useColors().getColors(ColorEnum.Dark);
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));
@@ -1,7 +1,10 @@
1
1
  <template>
2
2
  <FSCol>
3
3
  <slot v-if="!$props.hideHeader" name="label">
4
- <FSRow :wrap="false">
4
+ <FSRow
5
+ height="16px"
6
+ :wrap="false"
7
+ >
5
8
  <FSSpan
6
9
  v-if="$props.label"
7
10
  class="fs-text-field-label"
@@ -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">("validateOn", 'input');
5
- const submitted = inject<boolean>("submitted", false);
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.25",
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.25",
14
- "@dative-gpi/foundation-shared-services": "0.0.25",
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": "a390e06ed87cce4f2ae27570f474f5b52419327c"
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
+ }
@@ -30,6 +30,6 @@ a:has(.fs-clickable) {
30
30
  padding: 0 !important;
31
31
  }
32
32
 
33
- .fs-clickable-anchor-full-width {
33
+ .fs-clickable-wrapper-full-width {
34
34
  width: 100%;
35
35
  }
@@ -1,3 +1,4 @@
1
+ @import "fs_accordion_panel.scss";
1
2
  @import "fs_autocomplete_field.scss";
2
3
  @import "fs_breadcrumbs.scss";
3
4
  @import "fs_button.scss";
@@ -11,7 +11,7 @@
11
11
  // Applies to all inputs
12
12
  .v-input {
13
13
  padding: 0px !important;
14
- min-width: 240px;
14
+ min-width: 200px;
15
15
  width: 100%;
16
16
 
17
17
  & .v-input__prepend {