@fy-/fws-vue 2.1.6 → 2.1.7

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 (40) hide show
  1. package/components/fws/CmsArticleBoxed.vue +23 -20
  2. package/components/fws/CmsArticleSingle.vue +74 -68
  3. package/components/fws/DataTable.vue +132 -125
  4. package/components/fws/FilterData.vue +99 -101
  5. package/components/fws/UserData.vue +33 -32
  6. package/components/fws/UserFlow.vue +163 -155
  7. package/components/fws/UserOAuth2.vue +73 -72
  8. package/components/fws/UserProfile.vue +98 -101
  9. package/components/fws/UserProfileStrict.vue +65 -64
  10. package/components/ssr/ClientOnly.ts +7 -7
  11. package/components/ui/DefaultBreadcrumb.vue +13 -13
  12. package/components/ui/DefaultConfirm.vue +35 -34
  13. package/components/ui/DefaultDateSelection.vue +19 -17
  14. package/components/ui/DefaultDropdown.vue +25 -25
  15. package/components/ui/DefaultDropdownLink.vue +15 -14
  16. package/components/ui/DefaultGallery.vue +179 -168
  17. package/components/ui/DefaultInput.vue +121 -126
  18. package/components/ui/DefaultLoader.vue +17 -17
  19. package/components/ui/DefaultModal.vue +35 -33
  20. package/components/ui/DefaultNotif.vue +50 -52
  21. package/components/ui/DefaultPaging.vue +92 -95
  22. package/components/ui/DefaultSidebar.vue +29 -25
  23. package/components/ui/DefaultTagInput.vue +121 -119
  24. package/components/ui/transitions/CollapseTransition.vue +1 -1
  25. package/components/ui/transitions/ExpandTransition.vue +1 -1
  26. package/components/ui/transitions/FadeTransition.vue +1 -1
  27. package/components/ui/transitions/ScaleTransition.vue +1 -1
  28. package/components/ui/transitions/SlideTransition.vue +3 -3
  29. package/composables/event-bus.ts +10 -8
  30. package/composables/rest.ts +59 -56
  31. package/composables/seo.ts +106 -95
  32. package/composables/ssr.ts +64 -62
  33. package/composables/templating.ts +57 -57
  34. package/composables/translations.ts +13 -13
  35. package/env.d.ts +6 -4
  36. package/index.ts +101 -98
  37. package/package.json +7 -7
  38. package/stores/serverRouter.ts +25 -25
  39. package/stores/user.ts +79 -72
  40. package/types.d.ts +65 -65
@@ -1,112 +1,112 @@
1
1
  <script setup lang="ts">
2
- import useVuelidate from "@vuelidate/core";
3
- import DefaultInput from "../ui/DefaultInput.vue";
4
- import { useUserStore } from "../../stores/user";
5
- import { useRest } from "../../composables/rest";
6
- import { useEventBus } from "../../composables/event-bus";
7
- import { computed, reactive, watchEffect, ref } from "vue";
8
- import { required, helpers } from "@vuelidate/validators";
9
- import { useTranslation } from "../../composables/translations";
2
+ import useVuelidate from '@vuelidate/core'
3
+ import { helpers, required } from '@vuelidate/validators'
4
+ import { computed, reactive, watchEffect } from 'vue'
5
+ import { useEventBus } from '../../composables/event-bus'
6
+ import { useRest } from '../../composables/rest'
7
+ import { useTranslation } from '../../composables/translations'
8
+ import { useUserStore } from '../../stores/user'
9
+ import DefaultInput from '../ui/DefaultInput.vue'
10
10
 
11
- const rest = useRest();
11
+ const rest = useRest()
12
12
  const props = withDefaults(
13
13
  defineProps<{
14
- onCompleted?: (data: any) => void;
15
- termsText?: string;
16
- force18?: boolean;
14
+ onCompleted?: (data: any) => void
15
+ termsText?: string
16
+ force18?: boolean
17
17
  }>(),
18
18
  {
19
19
  onCompleted: () => {},
20
- termsText: "",
20
+ termsText: '',
21
21
  force18: false,
22
22
  },
23
- );
24
- const currentDate = new Date();
23
+ )
24
+ const currentDate = new Date()
25
25
  const defaultDate = new Date(
26
26
  currentDate.setFullYear(currentDate.getFullYear() - 18),
27
27
  )
28
28
  .toISOString()
29
- .split("T")[0];
29
+ .split('T')[0]
30
30
 
31
- const ageValidator = (value: any) => {
32
- const today = new Date();
33
- const birthDate = new Date(value);
34
- let age = today.getFullYear() - birthDate.getFullYear();
35
- const m = today.getMonth() - birthDate.getMonth();
36
- if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) age--;
37
- return age >= 18 && age <= 2020;
38
- };
39
- const userStore = useUserStore();
40
- const userData = computed(() => userStore.user);
41
- const eventBus = useEventBus();
31
+ function ageValidator(value: any) {
32
+ const today = new Date()
33
+ const birthDate = new Date(value)
34
+ let age = today.getFullYear() - birthDate.getFullYear()
35
+ const m = today.getMonth() - birthDate.getMonth()
36
+ if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) age--
37
+ return age >= 18 && age <= 2020
38
+ }
39
+ const userStore = useUserStore()
40
+ const userData = computed(() => userStore.user)
41
+ const eventBus = useEventBus()
42
42
  const state = reactive({
43
43
  userData: {
44
- Username: userData.value?.UserProfile?.Username || "",
45
- Gender: userData.value?.UserProfile?.Gender || "",
44
+ Username: userData.value?.UserProfile?.Username || '',
45
+ Gender: userData.value?.UserProfile?.Gender || '',
46
46
  Birthdate: userData.value?.UserProfile?.Birthdate || defaultDate,
47
47
  AcceptedTerms: userData.value?.AcceptedTerms || true,
48
48
  },
49
- });
49
+ })
50
50
  watchEffect(() => {
51
51
  state.userData = {
52
- Username: userData.value?.UserProfile?.Username || "",
53
- Gender: userData.value?.UserProfile?.Gender || "",
52
+ Username: userData.value?.UserProfile?.Username || '',
53
+ Gender: userData.value?.UserProfile?.Gender || '',
54
54
  Birthdate: userData.value?.UserProfile?.Birthdate
55
55
  ? new Date(userData.value?.UserProfile?.Birthdate.unixms)
56
- .toISOString()
57
- .split("T")[0]
56
+ .toISOString()
57
+ .split('T')[0]
58
58
  : defaultDate,
59
59
  AcceptedTerms: userData.value?.AcceptedTerms || true,
60
- };
61
- });
62
- const translate = useTranslation();
60
+ }
61
+ })
62
+ const translate = useTranslation()
63
63
  const rules = {
64
64
  userData: {
65
65
  Username: {
66
- required: required,
66
+ required,
67
67
  },
68
68
  Gender: {
69
- required: required,
69
+ required,
70
70
  },
71
71
  Birthdate: {
72
72
  required,
73
73
  ageValidator: props.force18
74
74
  ? helpers.withMessage(
75
- translate("fws_under_18_error_message"),
76
- ageValidator,
77
- )
75
+ translate('fws_under_18_error_message'),
76
+ ageValidator,
77
+ )
78
78
  : undefined,
79
79
  },
80
80
  AcceptedTerms: {
81
- required: required,
81
+ required,
82
82
  },
83
83
  },
84
- };
85
- const v$ = useVuelidate(rules, state);
84
+ }
85
+ const v$ = useVuelidate(rules, state)
86
86
 
87
- const patchUser = async () => {
88
- eventBus.emit("main-loading", true);
87
+ async function patchUser() {
88
+ eventBus.emit('main-loading', true)
89
89
  if (await v$.value.userData.$validate()) {
90
- const data = { ...state.userData };
91
- const birtdate = new Date(`${data.Birthdate}T00:00:00Z`);
90
+ const data = { ...state.userData }
91
+ const birtdate = new Date(`${data.Birthdate}T00:00:00Z`)
92
92
  try {
93
- const birtdateAtUnixms = birtdate.getTime();
94
- // @ts-ignore
95
- data.Birthdate = new Date(birtdateAtUnixms).toISOString().split("T")[0];
96
- } catch (e) {
97
- // @ts-ignore
98
- data.Birthdate = data.Birthdate.toISOString().split("T")[0];
93
+ const birtdateAtUnixms = birtdate.getTime()
94
+ data.Birthdate = new Date(birtdateAtUnixms).toISOString().split('T')[0]
95
+ }
96
+ catch {
97
+ // @ts-expect-error: Birthdate is a string
98
+ data.Birthdate = data.Birthdate.toISOString().split('T')[0]
99
99
  }
100
- const response = await rest("User/_ForceProfile", "PATCH", data);
101
- if (response && response.result == "success") {
100
+ const response = await rest('User/_ForceProfile', 'PATCH', data)
101
+ if (response && response.result === 'success') {
102
102
  if (props.onCompleted) {
103
- props.onCompleted(response);
103
+ props.onCompleted(response)
104
104
  }
105
- eventBus.emit("user:refresh", true);
105
+ eventBus.emit('user:refresh', true)
106
106
  }
107
107
  }
108
- eventBus.emit("main-loading", false);
109
- };
108
+ eventBus.emit('main-loading', false)
109
+ }
110
110
  </script>
111
111
 
112
112
  <template>
@@ -121,12 +121,11 @@ const patchUser = async () => {
121
121
  :error-vuelidate="v$.userData.Username.$errors"
122
122
  :disabled="userData?.UserProfile?.HasUsernameAndSlug ? true : false"
123
123
  />
124
- <!-- @vue-skip -->
125
124
  <DefaultInput
126
125
  id="birthdateFWS"
127
126
  v-model="state.userData.Birthdate"
128
127
  class="mb-4"
129
- :disableDatesUnder18="true"
128
+ :disable-dates-under18="true"
130
129
  type="datepicker"
131
130
  :label="$t('fws_birthdate_label')"
132
131
  :error-vuelidate="v$.userData.Birthdate.$errors"
@@ -154,7 +153,9 @@ const patchUser = async () => {
154
153
  :help="$t('fws_accepted_terms_help')"
155
154
  :error-vuelidate="v$.userData.AcceptedTerms.$errors"
156
155
  />
157
- <p class="terms-box" v-if="props.termsText">{{ props.termsText }}</p>
156
+ <p v-if="props.termsText" class="terms-box">
157
+ {{ props.termsText }}
158
+ </p>
158
159
 
159
160
  <div class="flex">
160
161
  <button type="submit" class="btn defaults primary">
@@ -1,12 +1,12 @@
1
- import { ref, onMounted, defineComponent } from "vue";
1
+ import { defineComponent, onMounted, ref } from 'vue'
2
2
 
3
3
  export const ClientOnly = defineComponent({
4
- __name: "ClientOnly",
4
+ __name: 'ClientOnly',
5
5
  setup(_, { slots }) {
6
- const show = ref(false);
6
+ const show = ref(false)
7
7
  onMounted(() => {
8
- show.value = true;
9
- });
10
- return () => (show.value && slots.default ? slots.default() : null);
8
+ show.value = true
9
+ })
10
+ return () => (show.value && slots.default ? slots.default() : null)
11
11
  },
12
- });
12
+ })
@@ -1,32 +1,32 @@
1
1
  <script lang="ts" setup>
2
- import { HomeIcon, ChevronRightIcon } from "@heroicons/vue/24/solid";
3
- import type { BreadcrumbLink } from "../../types";
4
- import { defineBreadcrumb, useSchemaOrg } from "@unhead/schema-org";
2
+ import type { BreadcrumbLink } from '../../types'
3
+ import { ChevronRightIcon, HomeIcon } from '@heroicons/vue/24/solid'
4
+ import { defineBreadcrumb, useSchemaOrg } from '@unhead/schema-org'
5
5
 
6
6
  const props = withDefaults(
7
7
  defineProps<{
8
- nav: BreadcrumbLink[];
9
- showHome: Boolean;
8
+ nav: BreadcrumbLink[]
9
+ showHome: boolean
10
10
  }>(),
11
11
  {
12
12
  nav: () => [],
13
13
  showHome: () => true,
14
14
  },
15
- );
15
+ )
16
16
 
17
17
  const breadcrumbsSchemaFormat = props.nav.map((item, index) => {
18
18
  return {
19
19
  position: index + 1,
20
20
  name: item.name,
21
21
  item: item.to,
22
- };
23
- });
22
+ }
23
+ })
24
24
 
25
25
  useSchemaOrg([
26
26
  defineBreadcrumb({
27
27
  itemListElement: breadcrumbsSchemaFormat,
28
28
  }),
29
- ]);
29
+ ])
30
30
  </script>
31
31
 
32
32
  <template>
@@ -34,9 +34,9 @@ useSchemaOrg([
34
34
  <template v-for="(item, index) in nav" :key="`bc_${index.toString()}`">
35
35
  <li class="inline-flex items-center">
36
36
  <ChevronRightIcon
37
- v-if="index != 0"
37
+ v-if="index !== 0"
38
38
  :class="
39
- index == 0
39
+ index === 0
40
40
  ? 'w-4 h-4 mr-2 inline-block'
41
41
  : 'w-5 h-5 text-fv-neutral-400 inline-block mx-0.5 md:mx-1.5'
42
42
  "
@@ -46,7 +46,7 @@ useSchemaOrg([
46
46
  v-if="item.to"
47
47
  :to="item.to"
48
48
  :class="
49
- index == 0
49
+ index === 0
50
50
  ? 'text-xs font-medium text-fv-neutral-700 hover:text-fv-neutral-900 dark:text-fv-neutral-200 dark:hover:text-white'
51
51
  : 'text-xs font-medium text-fv-neutral-700 hover:text-fv-neutral-900 dark:text-fv-neutral-200 dark:hover:text-white'
52
52
  "
@@ -54,7 +54,7 @@ useSchemaOrg([
54
54
  <HomeIcon
55
55
  v-if="showHome && index === 0"
56
56
  :class="
57
- index == 0
57
+ index === 0
58
58
  ? 'w-4 h-4 mr-2 inline-block'
59
59
  : 'w-4 h-4 text-fv-neutral-400 inline-block mx-0.5 md:mx-1.5'
60
60
  "
@@ -1,45 +1,46 @@
1
1
  <script setup lang="ts">
2
- import { ref, onMounted, onUnmounted } from "vue";
3
- import { useEventBus } from "../../composables/event-bus";
4
- import DefaultModal from "./DefaultModal.vue";
2
+ import { onMounted, onUnmounted, ref } from 'vue'
3
+ import { useEventBus } from '../../composables/event-bus'
4
+ import DefaultModal from './DefaultModal.vue'
5
5
 
6
- const eventBus = useEventBus();
7
- const title = ref<string | null>(null);
8
- const desc = ref<string | null>(null);
9
- const onConfirm = ref<Function | null>(null);
6
+ const eventBus = useEventBus()
7
+ const title = ref<string | null>(null)
8
+ const desc = ref<string | null>(null)
9
+ const onConfirm = ref<Function | null>(null)
10
10
  interface ConfirmModalData {
11
- title: string;
12
- desc: string;
13
- onConfirm: Function;
11
+ title: string
12
+ desc: string
13
+ onConfirm: Function
14
14
  }
15
- const _onConfirm = async () => {
15
+ async function _onConfirm() {
16
16
  if (onConfirm.value) {
17
- await onConfirm.value();
17
+ await onConfirm.value()
18
18
  }
19
- resetConfirm();
20
- };
21
- const resetConfirm = () => {
22
- title.value = null;
23
- desc.value = null;
24
- onConfirm.value = null;
25
- eventBus.emit("confirmModal", false);
26
- };
27
- const showConfirm = (data: ConfirmModalData) => {
28
- title.value = data.title;
29
- desc.value = data.desc;
30
- onConfirm.value = data.onConfirm;
31
- eventBus.emit("confirmModal", true);
32
- };
19
+ resetConfirm()
20
+ }
21
+ function resetConfirm() {
22
+ title.value = null
23
+ desc.value = null
24
+ onConfirm.value = null
25
+ eventBus.emit('confirmModal', false)
26
+ }
27
+ function showConfirm(data: ConfirmModalData) {
28
+ title.value = data.title
29
+ desc.value = data.desc
30
+ onConfirm.value = data.onConfirm
31
+ eventBus.emit('confirmModal', true)
32
+ }
33
33
 
34
34
  onMounted(() => {
35
- eventBus.on("resetConfirm", resetConfirm);
36
- eventBus.on("showConfirm", showConfirm);
37
- });
35
+ eventBus.on('resetConfirm', resetConfirm)
36
+ eventBus.on('showConfirm', showConfirm)
37
+ })
38
38
  onUnmounted(() => {
39
- eventBus.off("resetConfirm", resetConfirm);
40
- eventBus.off("showConfirm", showConfirm);
41
- });
39
+ eventBus.off('resetConfirm', resetConfirm)
40
+ eventBus.off('showConfirm', showConfirm)
41
+ })
42
42
  </script>
43
+
43
44
  <template>
44
45
  <DefaultModal id="confirm">
45
46
  <div
@@ -49,9 +50,9 @@ onUnmounted(() => {
49
50
  <p
50
51
  class="mb-3 !text-left prose prose-invert prose-sm !min-w-full"
51
52
  v-html="
52
- desc ? '<h2>' + title + '</h2>' + desc : '<h2>' + title + '</h2>'
53
+ desc ? `<h2>${title}</h2>${desc}` : `<h2>${title}</h2>`
53
54
  "
54
- ></p>
55
+ />
55
56
  <div class="flex justify-between gap-3 mt-4">
56
57
  <button class="btn danger defaults" @click="_onConfirm()">
57
58
  {{ $t("confirm_modal_cta_confirm") }}
@@ -1,40 +1,42 @@
1
1
  <script lang="ts" setup>
2
- import { computed } from "vue";
3
- import { DefaultInput } from "../..";
2
+ import { computed } from 'vue'
3
+ import { DefaultInput } from '../..'
4
+
4
5
  interface DateInterval {
5
- $between: [any, any];
6
+ $between: [any, any]
6
7
  }
7
8
  const props = withDefaults(
8
9
  defineProps<{
9
- mode?: "interval" | "single";
10
- modelValue?: DateInterval;
11
- id: string;
12
- label?: string;
10
+ mode?: 'interval' | 'single'
11
+ modelValue?: DateInterval
12
+ id: string
13
+ label?: string
13
14
  }>(),
14
15
  {
15
- mode: "single",
16
+ mode: 'single',
16
17
  modelValue: () => {
17
- return { $between: [undefined, undefined] };
18
+ return { $between: [undefined, undefined] }
18
19
  },
19
20
  },
20
- );
21
+ )
21
22
 
22
- const emit = defineEmits(["update:modelValue"]);
23
+ const emit = defineEmits(['update:modelValue'])
23
24
 
24
25
  const model = computed({
25
26
  get: () => props.modelValue,
26
27
  set: (items) => {
27
- emit("update:modelValue", items);
28
+ emit('update:modelValue', items)
28
29
  },
29
- });
30
+ })
30
31
  </script>
32
+
31
33
  <template>
32
- <div v-if="mode == 'interval' && model">
34
+ <div v-if="mode === 'interval' && model">
33
35
  <div class="flex flex-col md:flex-row">
34
36
  <DefaultInput
37
+ :id="`${id}_start`"
35
38
  v-model="model.$between[0]"
36
39
  type="date"
37
- :id="`${id}_start`"
38
40
  class="w-full"
39
41
  :label="`${label} (${$t('date_selection_start')})`"
40
42
  />
@@ -42,15 +44,15 @@ const model = computed({
42
44
  <div>↭</div>
43
45
  </div>
44
46
  <DefaultInput
47
+ :id="`${id}_end`"
45
48
  v-model="model.$between[1]"
46
49
  type="date"
47
50
  class="w-full"
48
- :id="`${id}_end`"
49
51
  :label="`${label} (${$t('date_selection_end')})`"
50
52
  />
51
53
  </div>
52
54
  </div>
53
55
  <div v-else>
54
- <DefaultInput v-model="model.$between[0]" type="date" :id="id" />
56
+ <DefaultInput :id="id" v-model="model.$between[0]" type="date" />
55
57
  </div>
56
58
  </template>
@@ -1,35 +1,35 @@
1
1
  <script setup lang="ts">
2
- import { onMounted, onUnmounted } from "vue";
2
+ import { onMounted, onUnmounted } from 'vue'
3
3
 
4
- import ScaleTransition from "./transitions/ScaleTransition.vue";
4
+ import ScaleTransition from './transitions/ScaleTransition.vue'
5
5
 
6
6
  const props = defineProps<{
7
- show: boolean;
8
- handleClickOutside: any;
9
- preventClickOutside?: boolean;
7
+ show: boolean
8
+ handleClickOutside: any
9
+ preventClickOutside?: boolean
10
10
  coordinates?: {
11
- left?: string;
12
- right?: string;
13
- top?: string;
14
- bottom?: string;
15
- };
16
- position: string[];
17
- closeDropdown: () => void;
18
- }>();
11
+ left?: string
12
+ right?: string
13
+ top?: string
14
+ bottom?: string
15
+ }
16
+ position: string[]
17
+ closeDropdown: () => void
18
+ }>()
19
19
 
20
- const handleCloseOnEscape = (event: KeyboardEvent) => {
21
- if (["Escape", "Esc"].includes(event.key)) {
22
- props.closeDropdown();
20
+ function handleCloseOnEscape(event: KeyboardEvent) {
21
+ if (['Escape', 'Esc'].includes(event.key)) {
22
+ props.closeDropdown()
23
23
  }
24
- };
24
+ }
25
25
 
26
26
  onMounted(() => {
27
- document.addEventListener("keydown", handleCloseOnEscape);
28
- });
27
+ document.addEventListener('keydown', handleCloseOnEscape)
28
+ })
29
29
 
30
30
  onUnmounted(() => {
31
- document.removeEventListener("keydown", handleCloseOnEscape);
32
- });
31
+ document.removeEventListener('keydown', handleCloseOnEscape)
32
+ })
33
33
  </script>
34
34
 
35
35
  <template>
@@ -37,14 +37,14 @@ onUnmounted(() => {
37
37
  <div
38
38
  v-if="props.show"
39
39
  class="fixed left-0 top-0 z-[50] w-full h-full"
40
- ></div>
40
+ />
41
41
 
42
42
  <ScaleTransition>
43
43
  <div
44
- :class="props.position"
45
- :style="props.coordinates"
46
44
  v-show="props.show"
47
45
  v-click-outside="props.handleClickOutside"
46
+ :class="props.position"
47
+ :style="props.coordinates"
48
48
  class="absolute z-[100] w-[200px] mt-2 rounded-sm bg-white dark:bg-fv-neutral-900 shadow-lg border border-fv-neutral-100 dark:border-fv-neutral-600 focus:outline-none"
49
49
  role="menu"
50
50
  aria-orientation="vertical"
@@ -52,7 +52,7 @@ onUnmounted(() => {
52
52
  tabindex="-1"
53
53
  >
54
54
  <div role="none">
55
- <slot></slot>
55
+ <slot />
56
56
  </div>
57
57
  </div>
58
58
  </ScaleTransition>
@@ -1,36 +1,37 @@
1
1
  <script setup lang="ts">
2
- import { computed } from "vue";
2
+ import { computed } from 'vue'
3
3
 
4
4
  const props = defineProps<{
5
- handleClick?: () => void;
6
- label?: string;
7
- color?: string;
8
- }>();
5
+ handleClick?: () => void
6
+ label?: string
7
+ color?: string
8
+ }>()
9
9
 
10
10
  const baseClasses = `w-full px-4 py-3 flex items-center border-b opacity-60
11
11
  dark:opacity-70 outline-none text-sm border-fv-neutral-200 dark:border-fv-neutral-600
12
- transition-all duration-200`;
12
+ transition-all duration-200`
13
13
 
14
14
  const colorClasses = computed(() => {
15
- if (props.color === "danger") {
16
- return "text-red-500 dark:hover:text-red-50 hover:bg-red-50 active:bg-red-100 dark:hover:bg-red-900";
17
- } else {
15
+ if (props.color === 'danger') {
16
+ return 'text-red-500 dark:hover:text-red-50 hover:bg-red-50 active:bg-red-100 dark:hover:bg-red-900'
17
+ }
18
+ else {
18
19
  return `text-black dark:text-white active:bg-fv-neutral-100 dark:hover:bg-fv-neutral-600
19
- dark:focus:bg-fv-neutral-600 hover:bg-fv-neutral-50`;
20
+ dark:focus:bg-fv-neutral-600 hover:bg-fv-neutral-50`
20
21
  }
21
- });
22
+ })
22
23
 
23
- const classes = computed(() => `${baseClasses} ${colorClasses.value}`);
24
+ const classes = computed(() => `${baseClasses} ${colorClasses.value}`)
24
25
  </script>
25
26
 
26
27
  <template>
27
28
  <button
28
29
  :aria-label="props.label"
29
- @click.prevent="props.handleClick"
30
30
  :class="classes"
31
31
  role="menuitem"
32
32
  type="button"
33
+ @click.prevent="props.handleClick"
33
34
  >
34
- <slot></slot>
35
+ <slot />
35
36
  </button>
36
37
  </template>