I cannot set the type of my custom input 🥲

Hi all,

I’m building a custom input (interface extension) to do some calculations behind the curtains before writing to DB and giving the user a feedback (it can’t be a hook).

Despite my zero knowledge of Vue, I was able to get some of it working. But there’s something that is not working no matter what: I cannot set the type of my input.

I need the resulted HTML to be of type “number”: <input ... type="number" /> but the type is always “string” (or “float” when I change the component options to types: ['float'] and the props value type to Number)

Here’s my code:

// index.ts
import { defineInterface } from "@directus/extensions-sdk";
import InterfaceComponent from "./interface.vue";

export default defineInterface({
  id: "myInput",
  name: "MyInput",
  icon: "box",
  description: "This is my custom interface!",
  component: InterfaceComponent,
  options: null,
  types: ["float"],
});
// interface.vue
<template>
  <VInput :model-value="dimension" @input="handleDimensionChange($event.target.value)" />
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
const emit = defineEmits(['input']);

const props = defineProps({
  value: {
    type: Number,
    default: null,
  },
});

const dimension = ref(props.value);

// observes when the value of props.value is actually received
// and updates the value of dimension (initially props.value is null)
// without this, the input doesn't show the persisted value
watch(() => props.value, () => {
  dimension.value = props.value;
});

function handleDimensionChange(value: string): void {
  emit('input', value);
}
</script>

I’ve tried adding type="number" and :type="'number'" to VInput with no success. It seems to work here though: VInput › default | Directus Components

p.s: As I said, I have zero knowledge of Vue (I’m used to React) so I believe that this may be a very silly question but I spent hours on it already. :frowning:

Hey there,

What you are doing with “type=number” should be correct!
Did you rebuild the extension (or start it in dev mode) and refreshed the page after it was done building?

I’m running Directus v11.3.5 (edit: tested on v11.7.2 - same behavior)

Ok, so I did some more tests. I was adding the interface extension to a existing bundle extension so I decided to start fresh and use only Javascript this time. Here are the steps that still fail!!

  1. Create a new interface extension using npx create-directus-extension@latest
âś” Choose the extension type interface
âś” Choose a name for the extension my-custom-input
âś” Choose the language to use javascript
âś” Auto install dependencies? Yes
âś” Done
  1. Change the created interface.vue file removing the following code
<input :value="value" @input="handleChange($event.target.value)" />

and adding the following code

<VInput
  :model-value="value"
  @input="handleChange($event.target.value)"
  type="number"
/>

We are changing one line only, using VInput instead of input.

  1. Boom! The type of the field on HTML is still string and not number :smiling_face_with_tear:

EXTRA

If I change the type of the value props to Number

props: {
    value: {
      type: Number,
      default: null,
    },
  }

and the index.js types to ['float']

export default {
	id: 'my-custom-input',
	name: 'My Custom Input',
	icon: 'box',
	description: 'This is my custom input!',
	component: InterfaceComponent,
	options: null,
	types: ['float'],
};

Now the HTML component is of type float. It’s not string anymore, but it is not number.


Looking at the Directus code for the input component, it seems it is doing exactly the same thing; I can’t see what I’m doing wrong: directus/app/src/interfaces/input/input.vue at 097a3d639522a68a327a8d55637fc7d4939fb283 · directus/directus · GitHub