@dative-gpi/foundation-shared-components 0.0.6 → 0.0.8

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 (37) hide show
  1. package/components/FSButton.vue +170 -164
  2. package/components/FSCalendar.vue +171 -0
  3. package/components/FSCalendarTwin.vue +394 -0
  4. package/components/FSCard.vue +63 -0
  5. package/components/FSCheckbox.vue +7 -8
  6. package/components/FSClock.vue +38 -0
  7. package/components/FSDatePicker.vue +226 -0
  8. package/components/FSIcon.vue +1 -1
  9. package/components/FSNumberField.vue +4 -4
  10. package/components/FSPasswordField.vue +14 -12
  11. package/components/FSRadio.vue +0 -1
  12. package/components/FSRadioGroup.vue +6 -6
  13. package/components/FSRichTextField.vue +558 -0
  14. package/components/FSSearchField.vue +103 -102
  15. package/components/FSSlider.vue +132 -0
  16. package/components/FSSwitch.vue +9 -9
  17. package/components/FSTagField.vue +186 -127
  18. package/components/FSTextArea.vue +207 -0
  19. package/components/FSTextField.vue +151 -146
  20. package/composables/index.ts +2 -1
  21. package/composables/useBreakpoints.ts +14 -0
  22. package/composables/useDates.ts +39 -0
  23. package/models/FSTextFields.ts +12 -6
  24. package/package.json +12 -4
  25. package/styles/components/fs_button.scss +2 -10
  26. package/styles/components/fs_calendar.scss +115 -0
  27. package/styles/components/fs_card.scss +7 -0
  28. package/styles/components/fs_date_picker.scss +0 -0
  29. package/styles/components/fs_icon.scss +3 -9
  30. package/styles/components/fs_rich_text_field.scss +67 -0
  31. package/styles/components/fs_slider.scss +20 -0
  32. package/styles/components/fs_tag_field.scss +9 -0
  33. package/styles/components/fs_text_area.scss +105 -0
  34. package/styles/components/index.scss +6 -0
  35. package/utils/FSRichTextField.ts +27 -0
  36. package/utils/index.ts +1 -0
  37. package/composables/useTouch.ts +0 -9
@@ -1,42 +1,42 @@
1
1
  <template>
2
- <v-btn
3
- v-if="!['icon'].includes($props.variant)"
4
- :ripple="false"
5
- :style="style"
6
- :class="classes"
7
- @click="onClick"
8
- v-bind="$attrs"
9
- >
10
- <FSRow :wrap="false">
11
- <slot name="prepend" v-bind="{ color, colors }">
12
- <FSIcon v-if="$props.prependIcon" size="m">
13
- {{ $props.prependIcon }}
14
- </FSIcon>
15
- </slot>
16
- <slot name="default" v-bind="{ color, colors }">
17
- <FSSpan v-if="$props.label" font="text-body">
18
- {{ $props.label }}
19
- </FSSpan>
20
- </slot>
21
- <slot name="append" v-bind="{ color, colors }">
22
- <FSIcon v-if="$props.appendIcon" size="m">
23
- {{ $props.appendIcon }}
24
- </FSIcon>
25
- </slot>
26
- </FSRow>
27
- </v-btn>
28
- <FSRow
29
- v-else-if="$props.icon"
30
- width="hug"
31
- :style="style"
32
- :class="classes"
33
- @click="onClick"
34
- v-bind="$attrs"
35
- >
36
- <FSIcon size="checkbox">
37
- {{ $props.icon }}
2
+ <v-btn
3
+ v-if="!['icon'].includes($props.variant!)"
4
+ :ripple="false"
5
+ :style="style"
6
+ :class="classes"
7
+ @click="onClick"
8
+ v-bind="$attrs"
9
+ >
10
+ <FSRow :wrap="false">
11
+ <slot name="prepend" v-bind="{ color, colors }">
12
+ <FSIcon v-if="$props.prependIcon" size="m">
13
+ {{ $props.prependIcon }}
38
14
  </FSIcon>
15
+ </slot>
16
+ <slot name="default" v-bind="{ color, colors }">
17
+ <FSSpan v-if="$props.label" font="text-body">
18
+ {{ $props.label }}
19
+ </FSSpan>
20
+ </slot>
21
+ <slot name="append" v-bind="{ color, colors }">
22
+ <FSIcon v-if="$props.appendIcon" size="m">
23
+ {{ $props.appendIcon }}
24
+ </FSIcon>
25
+ </slot>
39
26
  </FSRow>
27
+ </v-btn>
28
+ <FSRow
29
+ v-else-if="$props.icon"
30
+ width="hug"
31
+ :style="style"
32
+ :class="classes"
33
+ @click="onClick"
34
+ v-bind="$attrs"
35
+ >
36
+ <FSIcon size="m">
37
+ {{ $props.icon }}
38
+ </FSIcon>
39
+ </FSRow>
40
40
  </template>
41
41
 
42
42
  <script lang="ts">
@@ -50,141 +50,147 @@ import FSIcon from "./FSIcon.vue";
50
50
  import FSRow from "./FSRow.vue";
51
51
 
52
52
  export default defineComponent({
53
- name: "FSButton",
54
- components: {
55
- FSSpan,
56
- FSIcon,
57
- FSRow
53
+ name: "FSButton",
54
+ components: {
55
+ FSSpan,
56
+ FSIcon,
57
+ FSRow,
58
+ },
59
+ props: {
60
+ prependIcon: {
61
+ type: String,
62
+ required: false,
63
+ default: null,
58
64
  },
59
- props: {
60
- prependIcon: {
61
- type: String,
62
- required: false,
63
- default: null
64
- },
65
- label: {
66
- type: String,
67
- required: false,
68
- default: null
69
- },
70
- appendIcon: {
71
- type: String,
72
- required: false,
73
- default: null
74
- },
75
- icon: {
76
- type: String,
77
- required: false,
78
- default: null
79
- },
80
- variant: {
81
- type: String as PropType<"standard" | "full" | "icon">,
82
- required: false,
83
- default: "standard"
84
- },
85
- color: {
86
- type: String as PropType<ColorBase>,
87
- required: false,
88
- default: ColorBase.Dark
89
- },
90
- editable: {
91
- type: Boolean,
92
- required: false,
93
- default: true
94
- }
65
+ label: {
66
+ type: String,
67
+ required: false,
68
+ default: null,
95
69
  },
96
- emts: ["click"],
97
- setup(props, { emit }) {
98
- const { label, variant, color, editable } = toRefs(props);
99
-
100
- const textColors = useColors().getContrasts(color.value);
101
- const colors = useColors().getColors(color.value);
102
- const slots = useSlots();
70
+ appendIcon: {
71
+ type: String,
72
+ required: false,
73
+ default: null,
74
+ },
75
+ icon: {
76
+ type: String,
77
+ required: false,
78
+ default: null,
79
+ },
80
+ variant: {
81
+ type: String as PropType<"standard" | "full" | "icon">,
82
+ required: false,
83
+ default: "standard",
84
+ },
85
+ color: {
86
+ type: String as PropType<ColorBase>,
87
+ required: false,
88
+ default: ColorBase.Dark,
89
+ },
90
+ editable: {
91
+ type: Boolean,
92
+ required: false,
93
+ default: true,
94
+ },
95
+ },
96
+ emits: ["click"],
97
+ setup(props, { emit }) {
98
+ const { label, variant, color, editable } = toRefs(props);
103
99
 
104
- const lights = useColors().getColors(ColorBase.Light);
100
+ const textColors = useColors().getContrasts(color.value);
101
+ const colors = useColors().getColors(color.value);
102
+ const slots = useSlots();
105
103
 
106
- const isEmpty = computed(() => {
107
- return !slots.default && !label.value;
108
- });
104
+ const lights = useColors().getColors(ColorBase.Light);
109
105
 
110
- const style = computed((): {[code: string]: string} & Partial<CSSStyleDeclaration> => {
111
- if (!editable.value) {
112
- switch (variant.value) {
113
- case "standard":
114
- case "full": return {
115
- "--fs-button-padding": !isEmpty.value ? "0 16px" : "0",
116
- "--fs-button-background-color": lights.base,
117
- "--fs-button-border-color": lights.dark,
118
- "--fs-button-color": lights.dark
119
- }
120
- case "icon": return {
121
- "--fs-button-color": lights.dark
122
- }
123
- }
124
- }
125
- switch (variant.value) {
126
- case "standard": return {
127
- "--fs-button-padding": !isEmpty.value ? "0 16px" : "0",
128
- "--fs-button-background-color": colors.light,
129
- "--fs-button-border-color": colors.base,
130
- "--fs-button-color": textColors.base,
131
- "--fs-button-hover-background-color": colors.base,
132
- "--fs-button-hover-border-color": colors.base,
133
- "--fs-button-hover-color": textColors.light,
134
- "--fs-button-active-background-color": colors.dark,
135
- "--fs-button-active-border-color": colors.dark,
136
- "--fs-button-active-color": textColors.light
137
- };
138
- case "full": return {
139
- "--fs-button-padding" : !isEmpty.value ? "0 16px" : "0",
140
- "--fs-button-background-color": colors.base,
141
- "--fs-button-border-color": colors.base,
142
- "--fs-button-color": textColors.light,
143
- "--fs-button-hover-background-color": colors.base,
144
- "--fs-button-hover-border-color": colors.base,
145
- "--fs-button-hover-color": textColors.light,
146
- "--fs-button-active-background-color": colors.dark,
147
- "--fs-button-active-border-color": colors.dark,
148
- "--fs-button-active-color": textColors.light
106
+ const isEmpty = computed(() => {
107
+ return !slots.default && !label.value;
108
+ });
149
109
 
150
- };
151
- case "icon": return {
152
- "--fs-button-color": textColors.base,
153
- "--fs-button-hover-color" : textColors.dark
154
- };
155
- }
156
- });
110
+ const style = computed(
111
+ (): { [code: string]: string } & Partial<CSSStyleDeclaration> => {
112
+ if (!editable.value) {
113
+ switch (variant.value) {
114
+ case "standard":
115
+ case "full":
116
+ return {
117
+ "--fs-button-padding": !isEmpty.value ? "0 16px" : "0",
118
+ "--fs-button-background-color": lights.base,
119
+ "--fs-button-border-color": lights.dark,
120
+ "--fs-button-color": lights.dark,
121
+ };
122
+ case "icon":
123
+ return {
124
+ "--fs-button-color": lights.dark,
125
+ };
126
+ }
127
+ }
128
+ switch (variant.value) {
129
+ case "standard":
130
+ return {
131
+ "--fs-button-padding": !isEmpty.value ? "0 16px" : "0",
132
+ "--fs-button-background-color": colors.light,
133
+ "--fs-button-border-color": colors.base,
134
+ "--fs-button-color": textColors.base,
135
+ "--fs-button-hover-background-color": colors.base,
136
+ "--fs-button-hover-border-color": colors.base,
137
+ "--fs-button-hover-color": textColors.light,
138
+ "--fs-button-active-background-color": colors.dark,
139
+ "--fs-button-active-border-color": colors.dark,
140
+ "--fs-button-active-color": textColors.light,
141
+ };
142
+ case "full":
143
+ return {
144
+ "--fs-button-padding": !isEmpty.value ? "0 16px" : "0",
145
+ "--fs-button-background-color": colors.base,
146
+ "--fs-button-border-color": colors.base,
147
+ "--fs-button-color": textColors.light,
148
+ "--fs-button-hover-background-color": colors.base,
149
+ "--fs-button-hover-border-color": colors.base,
150
+ "--fs-button-hover-color": textColors.light,
151
+ "--fs-button-active-background-color": colors.dark,
152
+ "--fs-button-active-border-color": colors.dark,
153
+ "--fs-button-active-color": textColors.light,
154
+ };
155
+ case "icon":
156
+ return {
157
+ "--fs-button-color": textColors.base,
158
+ "--fs-button-hover-color": textColors.dark,
159
+ };
160
+ }
161
+ }
162
+ );
157
163
 
158
- const classes = computed((): string[] => {
159
- const classes = [];
160
- if (!editable.value) {
161
- classes.push("fs-button--disabled");
162
- }
163
- switch (variant.value) {
164
- case "icon":
165
- classes.push("fs-button-icon");
166
- break;
167
- default:
168
- classes.push("fs-button");
169
- break;
170
- }
171
- return classes;
172
- });
164
+ const classes = computed((): string[] => {
165
+ const classes: string[] = [];
166
+ if (!editable.value) {
167
+ classes.push("fs-button--disabled");
168
+ }
169
+ switch (variant.value) {
170
+ case "icon":
171
+ classes.push("fs-button-icon");
172
+ break;
173
+ default:
174
+ classes.push("fs-button");
175
+ break;
176
+ }
177
+ return classes;
178
+ });
173
179
 
174
- const onClick = () => {
175
- if (!editable.value) {
176
- return;
177
- }
178
- emit("click");
179
- }
180
+ const onClick = () => {
181
+ if (!editable.value) {
182
+ return;
183
+ }
184
+ emit("click");
185
+ };
180
186
 
181
- return {
182
- colors,
183
- color,
184
- style,
185
- classes,
186
- onClick
187
- };
188
- }
187
+ return {
188
+ colors,
189
+ color,
190
+ style,
191
+ classes,
192
+ onClick,
193
+ };
194
+ },
189
195
  });
190
- </script>
196
+ </script>
@@ -0,0 +1,171 @@
1
+ <template>
2
+ <FSCol>
3
+ <FSRow>
4
+ <FSSpan
5
+ v-if="$props.label"
6
+ class="fs-calendar-label"
7
+ font="text-overline"
8
+ >
9
+ {{ $props.label }}
10
+ </FSSpan>
11
+ </FSRow>
12
+ <FSCol
13
+ class="fs-calendar"
14
+ :style="style"
15
+ >
16
+ <FSRow
17
+ class="fs-calendar-header"
18
+ align="center-center"
19
+ >
20
+ <FSButton
21
+ size="l"
22
+ variant="icon"
23
+ icon="mdi-chevron-left"
24
+ @click="onClickPrevious"
25
+ />
26
+ <FSSpan
27
+ class="fs-calendar-text"
28
+ font="text-h3"
29
+ >
30
+ {{ text }}
31
+ </FSSpan>
32
+ <FSButton
33
+ size="l"
34
+ variant="icon"
35
+ icon="mdi-chevron-right"
36
+ @click="onClickNext"
37
+ />
38
+ </FSRow>
39
+ <div
40
+ class="fs-calendar-divider"
41
+ :style="style"
42
+ />
43
+ <v-locale-provider :locale="languageCode">
44
+ <v-date-picker-month
45
+ :month="innerMonth"
46
+ :year="innerYear"
47
+ :multiple="false"
48
+ :showAdjacentMonths="true"
49
+ :modelValue="datesTools.epochToPicker($props.modelValue)"
50
+ @update:modelValue="(value) => $emit('update:modelValue', datesTools.pickerToEpoch(value))"
51
+ @update:month="null"
52
+ @update:year="null"
53
+ />
54
+ </v-locale-provider>
55
+ </FSCol>
56
+ </FSCol>
57
+ </template>
58
+
59
+ <script lang="ts">
60
+ import { computed, defineComponent, PropType, ref, toRefs } from "vue";
61
+ import { useDate as useAdapter } from "vuetify/lib/composables/date/index.mjs";
62
+
63
+ import { useColors, useDates } from "@dative-gpi/foundation-shared-components/composables";
64
+ import { useLanguageCode } from "@dative-gpi/foundation-shared-services/composables";
65
+ import { ColorBase } from "@dative-gpi/foundation-shared-components/themes";
66
+
67
+ import FSButton from "./FSButton.vue";
68
+ import FSSpan from "./FSSpan.vue";
69
+ import FSCol from "./FSCol.vue";
70
+ import FSRow from "./FSRow.vue";
71
+
72
+ export default defineComponent({
73
+ name: "FSCalendar",
74
+ components: {
75
+ FSButton,
76
+ FSSpan,
77
+ FSCol,
78
+ FSRow
79
+ },
80
+ props: {
81
+ label: {
82
+ type: String,
83
+ required: false,
84
+ default: null
85
+ },
86
+ modelValue: {
87
+ type: Array as PropType<Array<number>>,
88
+ required: false,
89
+ default: null
90
+ },
91
+ color: {
92
+ type: String as PropType<ColorBase>,
93
+ required: false,
94
+ default: ColorBase.Dark
95
+ },
96
+ buttonColor: {
97
+ type: String as PropType<ColorBase>,
98
+ required: false,
99
+ default: ColorBase.Primary
100
+ }
101
+ },
102
+ setup(props) {
103
+ const { modelValue, color, buttonColor } = toRefs(props);
104
+
105
+ const languageCode = useLanguageCode().languageCode;
106
+ const datesTools = useDates();
107
+ const adapter = useAdapter();
108
+
109
+ const colors = useColors().getColors(color.value);
110
+ const buttonColors = useColors().getColors(buttonColor.value);
111
+
112
+ const backgrounds = useColors().getColors(ColorBase.Background);
113
+
114
+ const innerMonth = ref(modelValue.value.length ? datesTools.epochToPicker(modelValue.value)[0].getMonth() : new Date().getMonth());
115
+ const innerYear = ref(modelValue.value.length ? datesTools.epochToPicker(modelValue.value)[0].getFullYear() : new Date().getFullYear());
116
+
117
+ const style = computed((): {[code: string]: string} & Partial<CSSStyleDeclaration> => {
118
+ return {
119
+ "--fs-calendar-background-color" : backgrounds.base,
120
+ "--fs-calendar-hover-background-color" : buttonColors.light,
121
+ "--fs-calendar-active-background-color": buttonColors.base,
122
+ "--fs-calendar-border-color" : colors.base,
123
+ "--fs-calendar-hover-border-color" : buttonColors.base,
124
+ "--fs-calendar-active-border-color" : buttonColors.base,
125
+ "--fs-calendar-color" : colors.base,
126
+ "--fs-calendar-hover-color" : buttonColors.base,
127
+ "--fs-calendar-active-color" : buttonColors.light
128
+ };
129
+ });
130
+
131
+ const text = computed(() => {
132
+ adapter.locale = languageCode;
133
+ return adapter.format(
134
+ adapter.setYear(adapter.setMonth(adapter.date(), innerMonth.value), innerYear.value),
135
+ 'monthAndYear',
136
+ );
137
+ });
138
+
139
+ const onClickPrevious = (): void => {
140
+ if (innerMonth.value > 0) {
141
+ innerMonth.value--;
142
+ }
143
+ else {
144
+ innerYear.value--;
145
+ innerMonth.value = 11;
146
+ }
147
+ };
148
+
149
+ const onClickNext = (): void => {
150
+ if (innerMonth.value < 11) {
151
+ innerMonth.value++;
152
+ }
153
+ else {
154
+ innerYear.value++;
155
+ innerMonth.value = 0;
156
+ }
157
+ };
158
+
159
+ return {
160
+ languageCode,
161
+ style,
162
+ text,
163
+ innerMonth,
164
+ innerYear,
165
+ datesTools,
166
+ onClickPrevious,
167
+ onClickNext
168
+ };
169
+ }
170
+ });
171
+ </script>