fix type errors of components/form

This commit is contained in:
Lhcfl 2024-04-04 18:48:23 +08:00
parent 3abe6a0dfe
commit bfffd94ae5
13 changed files with 90 additions and 70 deletions

View File

@ -14,6 +14,7 @@
"caughtErrorsIgnorePattern": "^_",
"destructuredArrayIgnorePattern": "^_"
}
]
],
"vue/no-setup-props-destructure": "off"
}
}

View File

@ -36,7 +36,7 @@ const props = defineProps<{
}>();
const emit = defineEmits<{
(ev: "update:modelValue", v: boolean): void;
"update:modelValue": [v: boolean];
}>();
const button = ref<HTMLElement>();
@ -46,9 +46,9 @@ const toggle = () => {
emit("update:modelValue", !checked.value);
if (!checked.value) {
const rect = button.value.getBoundingClientRect();
const x = rect.left + button.value.offsetWidth / 2;
const y = rect.top + button.value.offsetHeight / 2;
const rect = button.value!.getBoundingClientRect();
const x = rect.left + button.value!.offsetWidth / 2;
const y = rect.top + button.value!.offsetHeight / 2;
os.popup(Ripple, { x, y, particle: false }, {}, "end");
}
};

View File

@ -26,7 +26,7 @@
@input="onInput"
/>
<datalist v-if="datalist" :id="id">
<option v-for="data in datalist" :value="data" />
<option v-for="data in datalist" :key="data" :value="data" />
</datalist>
<div ref="suffixEl" class="suffix">
<slot name="suffix"></slot>
@ -47,7 +47,7 @@
<script lang="ts" setup>
import { nextTick, onMounted, ref, toRefs, watch } from "vue";
import { debounce } from "throttle-debounce";
import { debounce as Debounce } from "throttle-debounce";
import MkButton from "@/components/MkButton.vue";
import { useInterval } from "@/scripts/use-interval";
import { i18n } from "@/i18n";
@ -72,7 +72,7 @@ const props = defineProps<{
autofocus?: boolean;
autocomplete?: string;
spellcheck?: boolean;
step?: any;
step?: number | string;
datalist?: string[];
inline?: boolean;
debounce?: boolean;
@ -82,10 +82,10 @@ const props = defineProps<{
}>();
const emit = defineEmits<{
(ev: "change", _ev: KeyboardEvent): void;
(ev: "change", _ev: Event): void;
(ev: "keydown", _ev: KeyboardEvent): void;
(ev: "enter"): void;
(ev: "update:modelValue", value: string | number): void;
(ev: "update:modelValue", value: string | number | null): void;
}>();
const { modelValue, type, autofocus } = toRefs(props);
@ -94,14 +94,15 @@ const id = Math.random().toString(); // TODO: uuid?
const focused = ref(false);
const changed = ref(false);
const invalid = ref(false);
const inputEl = ref<HTMLElement>();
const inputEl = ref<HTMLInputElement>();
const prefixEl = ref<HTMLElement>();
const suffixEl = ref<HTMLElement>();
const height = props.small ? 36 : props.large ? 40 : 38;
const focus = () => inputEl.value.focus();
const selectRange = (start, end) => inputEl.value.setSelectionRange(start, end);
const onInput = (ev: KeyboardEvent) => {
const focus = () => inputEl.value!.focus();
const selectRange = (start, end) =>
inputEl.value!.setSelectionRange(start, end);
const onInput = (ev: Event) => {
changed.value = true;
emit("change", ev);
};
@ -116,13 +117,13 @@ const onKeydown = (ev: KeyboardEvent) => {
const updated = () => {
changed.value = false;
if (type.value === "number") {
emit("update:modelValue", parseFloat(v.value));
emit("update:modelValue", Number.parseFloat(v.value as string));
} else {
emit("update:modelValue", v.value);
}
};
const debouncedUpdated = debounce(1000, updated);
const debouncedUpdated = Debounce(1000, updated);
watch(modelValue, (newValue) => {
v.value = newValue;
@ -137,7 +138,7 @@ watch(v, (_) => {
}
}
invalid.value = inputEl.value.validity.badInput;
invalid.value = inputEl.value!.validity.badInput;
});
//
@ -146,12 +147,12 @@ useInterval(
() => {
if (prefixEl.value) {
if (prefixEl.value.offsetWidth) {
inputEl.value.style.paddingLeft = prefixEl.value.offsetWidth + "px";
inputEl.value!.style.paddingLeft = `${prefixEl.value.offsetWidth}px`;
}
}
if (suffixEl.value) {
if (suffixEl.value.offsetWidth) {
inputEl.value.style.paddingRight = suffixEl.value.offsetWidth + "px";
inputEl.value!.style.paddingRight = `${suffixEl.value.offsetWidth}px`;
}
}
},

View File

@ -16,19 +16,22 @@
<script lang="ts" setup>
import { computed } from "vue";
// biome-ignore lint/suspicious/noExplicitAny:
type ValueType = any;
const props = defineProps<{
modelValue: any;
value: any;
modelValue: ValueType;
value: ValueType;
disabled: boolean;
}>();
const emit = defineEmits<{
(ev: "update:modelValue", value: any): void;
"update:modelValue": [value: ValueType];
}>();
const checked = computed(() => props.modelValue === props.value);
function toggle(x) {
function toggle(_ev: Event) {
if (props.disabled) return;
emit("update:modelValue", props.value);
}

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { defineComponent, h } from "vue";
import { type VNode, defineComponent, h } from "vue";
import MkRadio from "./radio.vue";
export default defineComponent({
@ -22,13 +22,17 @@ export default defineComponent({
},
},
render() {
let options = this.$slots.default();
const label = this.$slots.label && this.$slots.label();
const caption = this.$slots.caption && this.$slots.caption();
let options = this.$slots.default!();
const label = this.$slots.label && this.$slots.label!();
const caption = this.$slots.caption && this.$slots.caption!();
// Fragment
if (options.length === 1 && options[0].props == null)
options = options[0].children;
if (
options.length === 1 &&
options[0].props == null &&
Array.isArray(options[0].children)
)
options = options[0].children as VNode[];
return h(
"fieldset",
@ -60,7 +64,10 @@ export default defineComponent({
value: option.props?.value,
disabled: option.props?.disabled,
modelValue: this.value,
"onUpdate:modelValue": (value) => (this.value = value),
"onUpdate:modelValue": (value) => {
this.value = value;
return value;
},
},
option.children,
),
@ -83,7 +90,7 @@ export default defineComponent({
});
</script>
<style lang="scss">
<style lang="scss" scoped>
.novjtcto {
border: 0;
padding: 0;

View File

@ -21,7 +21,7 @@
@mouseleave="tooltipHide"
@input="
(x) => {
inputVal = x.target.value;
inputVal = Number((x.target as HTMLInputElement).value);
if (instant) onChange(x);
}
"
@ -29,6 +29,7 @@
<datalist v-if="showTicks && steps" :id="id">
<option
v-for="i in steps"
:key="`step-${i}`"
:value="i + min"
:label="(i + min).toString()"
></option>
@ -69,11 +70,11 @@ const props = withDefaults(
},
);
const inputEl = ref<HTMLElement>();
const inputEl = ref<HTMLInputElement>();
const inputVal = ref(props.modelValue);
const emit = defineEmits<{
(ev: "update:modelValue", value: number): void;
"update:modelValue": [value: number];
}>();
const steps = computed(() => {
@ -84,7 +85,7 @@ const steps = computed(() => {
}
});
function onChange(x) {
function onChange(_x) {
emit("update:modelValue", inputVal.value);
}

View File

@ -58,6 +58,7 @@ import * as os from "@/os";
import { useInterval } from "@/scripts/use-interval";
import { i18n } from "@/i18n";
import icon from "@/scripts/icon";
import type { MenuItem } from "@/types/menu";
const props = defineProps<{
modelValue: string | null;
@ -85,13 +86,13 @@ const focused = ref(false);
const opening = ref(false);
const changed = ref(false);
const invalid = ref(false);
const inputEl = ref(null);
const prefixEl = ref(null);
const suffixEl = ref(null);
const container = ref(null);
const inputEl = ref<HTMLInputElement | null>(null);
const prefixEl = ref<HTMLElement | null>(null);
const suffixEl = ref<HTMLElement | null>(null);
const container = ref<HTMLElement | null>(null);
const height = props.small ? 33 : props.large ? 39 : 36;
const focus = () => inputEl.value.focus();
const focus = () => inputEl.value!.focus();
const onInput = (ev) => {
changed.value = true;
emit("change", ev);
@ -106,26 +107,27 @@ watch(modelValue, (newValue) => {
v.value = newValue;
});
watch(v, (newValue) => {
watch(v, (_newValue) => {
if (!props.manualSave) {
updated();
}
invalid.value = inputEl.value.validity.badInput;
invalid.value = inputEl.value!.validity.badInput;
});
//
// 0
useInterval(
() => {
if (inputEl.value == null) return;
if (prefixEl.value) {
if (prefixEl.value.offsetWidth) {
inputEl.value.style.paddingLeft = prefixEl.value.offsetWidth + "px";
inputEl.value.style.paddingLeft = `${prefixEl.value.offsetWidth}px`;
}
}
if (suffixEl.value) {
if (suffixEl.value.offsetWidth) {
inputEl.value.style.paddingRight = suffixEl.value.offsetWidth + "px";
inputEl.value.style.paddingRight = `${suffixEl.value.offsetWidth}px`;
}
}
},
@ -144,19 +146,19 @@ onMounted(() => {
});
});
function show(ev: MouseEvent) {
function show(_ev: MouseEvent) {
focused.value = true;
opening.value = true;
const menu = [];
const menu: MenuItem[] = [];
const options = slots.default!();
const pushOption = (option: VNode) => {
menu.push({
text: option.children,
active: computed(() => v.value === option.props.value),
text: option.children as string,
active: computed(() => v.value === option.props?.value).value,
action: () => {
v.value = option.props.value;
v.value = option.props?.value;
},
});
};
@ -167,13 +169,13 @@ function show(ev: MouseEvent) {
const optgroup = vnode;
menu.push({
type: "label",
text: optgroup.props.label,
text: optgroup.props?.label,
});
scanOptions(optgroup.children);
scanOptions(optgroup.children as VNode[]);
} else if (Array.isArray(vnode.children)) {
//
const fragment = vnode;
scanOptions(fragment.children);
scanOptions(fragment.children as VNode[]);
} else if (vnode.props == null) {
// v-if false
// nop?
@ -186,12 +188,13 @@ function show(ev: MouseEvent) {
scanOptions(options);
os.popupMenu(menu, container.value, {
width: container.value.offsetWidth,
onClosing: () => {
opening.value = false;
},
os.popupMenu(menu, container.value!, {
width: container.value!.offsetWidth,
// onClosing: () => {
// opening.value = false;
// },
}).then(() => {
opening.value = false;
focused.value = false;
});
}

View File

@ -14,7 +14,7 @@ const props = withDefaults(
},
);
const minWidth = props.minWidth + "px";
const minWidth = `${props.minWidth}px`;
</script>
<style lang="scss" scoped>

View File

@ -39,12 +39,13 @@ export default defineComponent({
props: {
p: {
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
type: Function as PropType<() => Promise<any>>,
required: true,
},
},
setup(props, context) {
setup(props, _context) {
const pending = ref(true);
const resolved = ref(false);
const rejected = ref(false);

View File

@ -2,7 +2,7 @@
<label class="ziffeomt">
<input
type="checkbox"
:checked="modelValue"
:checked="toValue(modelValue)"
:disabled="disabled"
@change="(x) => toggle(x)"
/>
@ -18,7 +18,7 @@
</template>
<script lang="ts" setup>
import type { Ref } from "vue";
import { type Ref, toValue } from "vue";
const props = defineProps<{
modelValue: boolean | Ref<boolean>;
@ -26,12 +26,12 @@ const props = defineProps<{
}>();
const emit = defineEmits<{
(ev: "update:modelValue", v: boolean): void;
"update:modelValue": [v: boolean];
}>();
function toggle(x) {
function toggle(x: Event) {
if (props.disabled) return;
emit("update:modelValue", x.target.checked);
emit("update:modelValue", (x.target as HTMLInputElement).checked);
}
</script>

View File

@ -60,6 +60,7 @@ export default defineComponent({
props: {
modelValue: {
type: String,
required: true,
},
type: {
@ -92,9 +93,11 @@ export default defineComponent({
default: false,
},
autocomplete: {
type: String,
required: false,
},
spellcheck: {
type: Boolean,
required: false,
},
code: {
@ -132,9 +135,9 @@ export default defineComponent({
const changed = ref(false);
const invalid = ref(false);
const filled = computed(() => v.value !== "" && v.value != null);
const inputEl = ref(null);
const inputEl = ref<HTMLTextAreaElement | null>(null);
const focus = () => inputEl.value.focus();
const focus = () => inputEl.value!.focus();
const onInput = (ev) => {
changed.value = true;
context.emit("change", ev);
@ -167,7 +170,7 @@ export default defineComponent({
}
}
invalid.value = inputEl.value.validity.badInput;
invalid.value = inputEl.value!.validity.badInput;
});
onMounted(() => {

View File

@ -27,7 +27,7 @@ const props = withDefaults(
const _time =
props.time == null
? NaN
? Number.NaN
: typeof props.time === "number"
? props.time
: (props.time instanceof Date

View File

@ -855,8 +855,8 @@ export function popupMenu(
noReturnFocus?: boolean;
},
) {
return new Promise((resolve, reject) => {
let dispose;
return new Promise<void>((resolve, _reject) => {
let dispose: () => void;
popup(
defineAsyncComponent({
loader: () => import("@/components/MkPopupMenu.vue"),