typeをジェネリック型に

This commit is contained in:
takejohn 2025-01-04 07:26:31 +00:00
parent 24ad5be5b1
commit 48df2adeb1
No known key found for this signature in database
GPG Key ID: 73120CE9760541C4
1 changed files with 36 additions and 13 deletions

View File

@ -43,17 +43,17 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup generic="T extends InputTypeHTMLAttribute">
import { onMounted, onUnmounted, nextTick, ref, shallowRef, watch, computed, toRefs, InputHTMLAttributes } from 'vue'; import { onMounted, onUnmounted, nextTick, ref, shallowRef, watch, computed, toRefs, InputTypeHTMLAttribute, InputHTMLAttributes } from 'vue';
import { debounce } from 'throttle-debounce'; import { debounce } from 'throttle-debounce';
import MkButton from '@/components/MkButton.vue';
import { useInterval } from '@@/js/use-interval.js'; import { useInterval } from '@@/js/use-interval.js';
import MkButton from '@/components/MkButton.vue';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { Autocomplete, SuggestionType } from '@/scripts/autocomplete.js'; import { Autocomplete, SuggestionType } from '@/scripts/autocomplete.js';
const props = defineProps<{ interface MkInputProps {
modelValue: string | number | null; modelValue: string | number | null;
type?: InputHTMLAttributes['type']; type?: T;
required?: boolean; required?: boolean;
readonly?: boolean; readonly?: boolean;
disabled?: boolean; disabled?: boolean;
@ -74,17 +74,40 @@ const props = defineProps<{
manualSave?: boolean; manualSave?: boolean;
small?: boolean; small?: boolean;
large?: boolean; large?: boolean;
}>(); }
type MkInputValue = T extends 'number' ? number : string;
const props = defineProps<MkInputProps>();
const emit = defineEmits<{ const emit = defineEmits<{
(ev: 'change', _ev: KeyboardEvent): void; (ev: 'change', _ev: KeyboardEvent): void;
(ev: 'keydown', _ev: KeyboardEvent): void; (ev: 'keydown', _ev: KeyboardEvent): void;
(ev: 'enter', _ev: KeyboardEvent): void; (ev: 'enter', _ev: KeyboardEvent): void;
(ev: 'update:modelValue', value: string | number): void; (ev: 'update:modelValue', value: MkInputValue): void;
}>(); }>();
const { modelValue, type, autofocus } = toRefs(props); const {
const v = ref(modelValue.value); modelValue,
type,
required,
readonly,
disabled,
pattern,
placeholder,
autofocus,
autocomplete,
autocapitalize,
spellcheck,
inputmode,
step,
datalist,
min,
max,
inline,
manualSave,
} = toRefs<MkInputProps>(props);
const v = ref<string | number | null>(modelValue.value);
const id = Math.random().toString(); // TODO: uuid? const id = Math.random().toString(); // TODO: uuid?
const focused = ref(false); const focused = ref(false);
const changed = ref(false); const changed = ref(false);
@ -117,10 +140,10 @@ const onKeydown = (ev: KeyboardEvent) => {
const updated = () => { const updated = () => {
changed.value = false; changed.value = false;
if (type.value === 'number') { if (type?.value === 'number') {
emit('update:modelValue', typeof v.value === 'number' ? v.value : parseFloat(v.value ?? '0')); emit('update:modelValue', (typeof v.value === 'number' ? v.value : parseFloat((v.value as string | null) ?? '0')) as MkInputValue);
} else { } else {
emit('update:modelValue', v.value ?? ''); emit('update:modelValue', (v.value ?? '') as MkInputValue);
} }
}; };
@ -164,7 +187,7 @@ useInterval(() => {
onMounted(() => { onMounted(() => {
nextTick(() => { nextTick(() => {
if (autofocus.value) { if (autofocus?.value) {
focus(); focus();
} }
}); });