- second commit
This commit is contained in:
parent
4fc3bb0a01
commit
59a99ff3c8
61 changed files with 2625 additions and 1182 deletions
|
@ -3,66 +3,71 @@ import { computed, ref, onMounted, onBeforeUnmount } from 'vue';
|
|||
import { MainService } from '@/Stores/main';
|
||||
import FormControlIcon from '@/Components/FormControlIcon.vue';
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
autocomplete: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
inputmode: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text',
|
||||
},
|
||||
modelValue: {
|
||||
type: [String, Number, Boolean, Array, Object],
|
||||
default: '',
|
||||
},
|
||||
required: Boolean,
|
||||
borderless: Boolean,
|
||||
transparent: Boolean,
|
||||
ctrlKFocus: Boolean,
|
||||
name: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
autocomplete: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
inputmode: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
options: {
|
||||
type: [Array, Object],
|
||||
default: null,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text',
|
||||
},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
modelValue: {
|
||||
type: [String, Number, Boolean, Array, Object],
|
||||
default: '',
|
||||
},
|
||||
required: Boolean,
|
||||
borderless: Boolean,
|
||||
transparent: Boolean,
|
||||
ctrlKFocus: Boolean,
|
||||
});
|
||||
const emit = defineEmits(['update:modelValue', 'setRef']);
|
||||
const computedValue = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => {
|
||||
emit('update:modelValue', value);
|
||||
},
|
||||
get: () => props.modelValue,
|
||||
set: (value) => {
|
||||
emit('update:modelValue', value);
|
||||
},
|
||||
});
|
||||
const inputElClass = computed(() => {
|
||||
const base = [
|
||||
'px-3 py-2 max-w-full focus:ring focus:outline-none border-gray-700 rounded w-full',
|
||||
'dark:placeholder-gray-400',
|
||||
computedType.value === 'textarea' ? 'h-24' : 'h-12',
|
||||
props.borderless ? 'border-0' : 'border',
|
||||
props.transparent ? 'bg-transparent' : 'bg-white dark:bg-slate-800',
|
||||
];
|
||||
if (props.icon) {
|
||||
base.push('pl-10');
|
||||
}
|
||||
return base;
|
||||
const base = [
|
||||
'px-3 py-2 max-w-full focus:ring focus:outline-none border-gray-700 rounded w-full',
|
||||
'dark:placeholder-gray-400',
|
||||
computedType.value === 'textarea' ? 'h-24' : 'h-12',
|
||||
props.borderless ? 'border-0' : 'border',
|
||||
// props.transparent && !props.isReadOnly ? 'bg-transparent' : 'bg-white dark:bg-slate-800',
|
||||
props.isReadOnly ? 'bg-gray-50 dark:bg-slate-600' : 'bg-white dark:bg-slate-800',
|
||||
];
|
||||
if (props.icon) {
|
||||
base.push('pl-10');
|
||||
}
|
||||
return base;
|
||||
});
|
||||
const computedType = computed(() => (props.options ? 'select' : props.type));
|
||||
const controlIconH = computed(() => (props.type === 'textarea' ? 'h-full' : 'h-12'));
|
||||
|
@ -71,74 +76,70 @@ const selectEl = ref(null);
|
|||
const textareaEl = ref(null);
|
||||
const inputEl = ref(null);
|
||||
onMounted(() => {
|
||||
if (selectEl.value) {
|
||||
emit('setRef', selectEl.value);
|
||||
} else if (textareaEl.value) {
|
||||
emit('setRef', textareaEl.value);
|
||||
} else {
|
||||
emit('setRef', inputEl.value);
|
||||
}
|
||||
if (selectEl.value) {
|
||||
emit('setRef', selectEl.value);
|
||||
} else if (textareaEl.value) {
|
||||
emit('setRef', textareaEl.value);
|
||||
} else {
|
||||
emit('setRef', inputEl.value);
|
||||
}
|
||||
});
|
||||
if (props.ctrlKFocus) {
|
||||
const fieldFocusHook = (e) => {
|
||||
if (e.ctrlKey && e.key === 'k') {
|
||||
e.preventDefault();
|
||||
inputEl.value.focus();
|
||||
} else if (e.key === 'Escape') {
|
||||
inputEl.value.blur();
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
if (!mainService.isFieldFocusRegistered) {
|
||||
window.addEventListener('keydown', fieldFocusHook);
|
||||
mainService.isFieldFocusRegistered = true;
|
||||
} else {
|
||||
// console.error('Duplicate field focus event')
|
||||
}
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('keydown', fieldFocusHook);
|
||||
mainService.isFieldFocusRegistered = false;
|
||||
});
|
||||
const fieldFocusHook = (e) => {
|
||||
if (e.ctrlKey && e.key === 'k') {
|
||||
e.preventDefault();
|
||||
inputEl.value.focus();
|
||||
} else if (e.key === 'Escape') {
|
||||
inputEl.value.blur();
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
if (!mainService.isFieldFocusRegistered) {
|
||||
window.addEventListener('keydown', fieldFocusHook);
|
||||
mainService.isFieldFocusRegistered = true;
|
||||
} else {
|
||||
// console.error('Duplicate field focus event')
|
||||
}
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('keydown', fieldFocusHook);
|
||||
mainService.isFieldFocusRegistered = false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative">
|
||||
<select
|
||||
v-if="computedType === 'select'"
|
||||
:id="id"
|
||||
v-model="computedValue"
|
||||
:name="name"
|
||||
:class="inputElClass"
|
||||
>
|
||||
<option v-for="option in options" :key="option.id ?? option" :value="option">
|
||||
{{ option.label ?? option }}
|
||||
</option>
|
||||
</select>
|
||||
<textarea
|
||||
v-else-if="computedType === 'textarea'"
|
||||
:id="id"
|
||||
v-model="computedValue"
|
||||
:class="inputElClass"
|
||||
:name="name"
|
||||
:placeholder="placeholder"
|
||||
:required="required"
|
||||
/>
|
||||
<input
|
||||
v-else
|
||||
:id="id"
|
||||
ref="inputEl"
|
||||
v-model="computedValue"
|
||||
:name="name"
|
||||
:inputmode="inputmode"
|
||||
:autocomplete="autocomplete"
|
||||
:required="required"
|
||||
:placeholder="placeholder"
|
||||
:type="computedType"
|
||||
:class="inputElClass"
|
||||
/>
|
||||
<FormControlIcon v-if="icon" :icon="icon" :h="controlIconH" />
|
||||
<slot />
|
||||
</div>
|
||||
<div class="relative">
|
||||
<select v-if="computedType === 'select'" :id="id" v-model="computedValue" :name="name" :class="inputElClass">
|
||||
<option v-if="placeholder" class="text-opacity-25" value="" disabled selected>{{ placeholder }}</option>
|
||||
<option v-for="option in options" :key="option.id ?? option" :value="option.value ?? option">
|
||||
{{ option.label ?? option }}
|
||||
</option>
|
||||
</select>
|
||||
<textarea
|
||||
v-else-if="computedType === 'textarea'"
|
||||
:id="id"
|
||||
v-model="computedValue"
|
||||
:class="inputElClass"
|
||||
:name="name"
|
||||
:placeholder="placeholder"
|
||||
:required="required"
|
||||
/>
|
||||
<input
|
||||
v-else
|
||||
:id="id"
|
||||
ref="inputEl"
|
||||
v-model="computedValue"
|
||||
:name="name"
|
||||
:inputmode="inputmode"
|
||||
:autocomplete="autocomplete"
|
||||
:required="required"
|
||||
:placeholder="placeholder"
|
||||
:type="computedType"
|
||||
:class="inputElClass"
|
||||
:readonly="isReadOnly"
|
||||
/>
|
||||
<FormControlIcon v-if="icon" :icon="icon" :h="controlIconH" />
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue