feat: add input component

This commit is contained in:
Alexandr
2022-08-03 14:55:16 +03:00
parent 96036c27e8
commit d3921ad9df
18 changed files with 590 additions and 380 deletions

View File

@@ -0,0 +1,58 @@
<template>
<div>
<label v-if="label" :class="labelClasses">{{ label }}</label>
<div class="flex relative">
<div v-if="$slots.prefix" class="w-10 flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none overflow-hidden">
<slot name="prefix" />
</div>
<input
v-bind="$attrs"
v-model="model"
:disabled="disabled"
:type="type"
:class="[inputClasses, $slots.prefix ? 'pl-10' : '']"
/>
<div v-if="$slots.suffix" class="absolute right-2.5 bottom-2.5">
<slot name="suffix" />
</div>
</div>
<p v-if="$slots.helper" class="mt-2 text-sm text-gray-500 dark:text-gray-400">
<slot name="helper" />
</p>
</div>
</template>
<script lang="ts" setup>
import type { PropType } from 'vue'
import type { InputSize } from '@/components/Input/types'
import { useInputClasses } from '@/components/Input/composables/useInputClasses'
import { toRefs } from 'vue'
import { useVModel } from '@vueuse/core'
const props = defineProps({
label: {
type: String,
default: '',
},
disabled: {
type: Boolean,
default: false,
},
type: {
type: String as PropType<'text' | 'password'>,
default: 'text',
},
size: {
type: String as PropType<InputSize>,
default: 'md',
},
modelValue: {
type: String,
default: '',
},
})
const model = useVModel(props, 'modelValue')
const {inputClasses, labelClasses} = useInputClasses(toRefs(props))
</script>

View File

@@ -0,0 +1,39 @@
import type { Ref } from 'vue'
import { computed } from 'vue'
import type { InputSize } from '@/components/Input/types'
import { simplifyTailwindClasses } from '@/utils/simplifyTailwindClasses'
// LABEL
const defaultLabelClasses = 'block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300'
// INPUT
const defaultInputClasses = 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500'
const disabledInputClasses = 'cursor-not-allowed bg-gray-100'
const inputSizeClasses: Record<InputSize, string> = {
lg: 'p-4',
md: 'p-2.5 text-sm',
sm: 'p-2 text-sm',
}
export type UseInputClassesProps = {
size: Ref<InputSize>
disabled: Ref<boolean>
}
export function useInputClasses(props: UseInputClassesProps): {
inputClasses: Ref<string>
labelClasses: Ref<string>
} {
const inputClasses = computed(() => {
return simplifyTailwindClasses(defaultInputClasses, inputSizeClasses[props.size.value], props.disabled.value ? disabledInputClasses : '')
})
const labelClasses = computed(() => {
return defaultLabelClasses
})
return {
inputClasses,
labelClasses,
}
}

View File

@@ -0,0 +1 @@
export type InputSize = 'sm' | 'md' | 'lg'