Bläddra i källkod

add the number input

Olivier Massot 2 år sedan
förälder
incheckning
e76489921a
1 ändrade filer med 108 tillägg och 0 borttagningar
  1. 108 0
      components/Ui/Input/Number.vue

+ 108 - 0
components/Ui/Input/Number.vue

@@ -0,0 +1,108 @@
+<!--
+An input for numeric values
+-->
+
+<template>
+  <v-text-field
+      ref="input"
+      :modelValue.number="modelValue"
+      hide-details
+      single-line
+      :density="density"
+      type="number"
+      @update:modelValue="modelValue = keepInRange(cast($event)); emitUpdate()"
+  />
+</template>
+
+<script setup lang="ts">
+
+import {PropType} from "@vue/runtime-core";
+
+type Density = null | 'default' | 'comfortable' | 'compact';
+
+const props = defineProps({
+  modelValue: {
+    type: Number,
+    required: true
+  },
+  default: {
+    type: Number,
+    required: false,
+    default: 0
+  },
+  min: {
+    type: Number,
+    required: false,
+    default: null
+  },
+  max: {
+    type: Number,
+    required: false,
+    default: null
+  },
+  density: {
+    type: String as PropType<Density>,
+    required: false,
+    default: 'default'
+  }
+})
+
+/**
+ * Reference to the v-text-field
+ */
+const input: Ref<any> = ref(null)
+
+/**
+ * Cast the value to a number, or fallback on default value
+ * @param val
+ */
+const cast = (val: number | string): number => {
+  val = Number(val)
+  if (isNaN(val)) {
+    return props.default
+  }
+
+  return val
+}
+
+/**
+ * Ensure the value is between min and max values
+ * @param val
+ */
+const keepInRange = (val: number) => {
+  if (props.min !== null && props.max !== null && props.min >= props.max) {
+    console.warn('Number input: minimum value is greater than maximum value')
+  }
+  if (props.min !== null && val < props.min) {
+    val = props.min
+  }
+  if (props.max !== null && val > props.max) {
+    val = props.max
+  }
+  return val
+}
+
+
+const emit = defineEmits(['update:modelValue'])
+
+/**
+ * Emit the update event
+ */
+const emitUpdate = () => {
+  emit('update:modelValue', props.modelValue)
+}
+
+/**
+ * Setup min and max values at the input level
+ */
+onMounted(() => {
+  console.log(input.value)
+  const inputElement = input.value.$el.querySelector('input')
+  if (props.min !== null) {
+    inputElement.min = props.min
+  }
+  if (props.max !== null) {
+    inputElement.max = props.max
+  }
+})
+</script>