I have a Button
component with the following code:
<script lang="ts" setup>
import { computed, ref } from 'vue';
const props = withDefaults(defineProps<{
href?: string;
type: 'button' | 'submit' | 'reset' | undefined;
color: string;
disabled: boolean;
}>(), {
type: 'button',
color: 'primary',
disabled: false,
});
const element = ref<HTMLElement | null>(null);
defineExpose({
focus: () => {
if (element.value) {
element.value.focus();
}
},
});
const style =
'inline-flex justify-center rounded-sm shadow-sm px-3 py-2 text-sm font-semibold focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus:outline focus:outline-2 focus:outline-offset-2';
const colors = new Map([
[
'primary',
'bg-lime-600 text-white hover:bg-lime-700 focus-visible:outline-lime-700 focus:outline-lime-700',
],
[
'base',
'bg-neutral-600 text-white hover:bg-neutral-700 focus-visible:outline-neutral-700 focus:outline-neutral-700',
],
[
'red',
'bg-red-600 text-white hover:bg-red-700 focus-visible:outline-red-700 focus:outline-red-700',
],
[
'white',
'bg-white text-neutral-900 ring-1 ring-inset ring-neutral-300 hover:bg-neutral-50 focus-visible:outline-neutral-400 focus:outline-neutral-400',
],
]);
const disabled = computed(() =>
props.disabled ? ' opacity-50 cursor-not-allowed' : null
);
const styles = computed(
() => `${style} ${colors.get(props.color)}${disabled.value}`
);
</script>
<template>
<a v-if="href" ref="element" :class="styles" :href="href">
<slot />
</a>
<button v-else ref="element" :class="styles" :type="type">
<slot />
</button>
</template>
and I’m using it from within another component as such:
<script lang="ts" setup>
import Button from '@/components/Button.vue';
import { onMounted, ref } from 'vue';
const emit = defineEmits(['cancel', 'proceed']);
const buttonRef = ref<HTMLElement | null>(null);
onMounted(() => {
if (buttonRef.value) {
buttonRef.value.focus();
}
});
</script>
<template>
<div>
// ...
<div class="mt-6 grid grid-flow-row-dense grid-cols-2 gap-3">
<Button ref="buttonRef" @click="emit('cancel')">Abort</Button>
<Button color="red" @click="emit('proceed')">
<slot name="button" />
</Button>
</div>
</div>
</template>
When I compile the code for production I get the error:
Argument of type ‘{ ref: string; onClick: any; }’ is not assignable to parameter of type ‘{ readonly href?: string | undefined; readonly type: “button” | “submit” | “reset” | undefined; readonly color: string; readonly disabled: boolean; } & VNodeProps & … 4 more … & Record<…>’.
Type ‘{ ref: string; onClick: any; }’ is missing the following properties from type ‘{ readonly href?: string | undefined; readonly type: “button” | “submit” | “reset” | undefined; readonly color: string; readonly disabled: boolean; }’: type, color, disabled
<Button ref=”buttonRef” @click=”emit(‘cancel’)”>Abort
Cannot figure out how to resolve it so any help would be much appreciated.