use define model
This commit is contained in:
@@ -1,24 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { vOnClickOutside } from '@vueuse/components';
|
import { vOnClickOutside } from '@vueuse/components';
|
||||||
import { useEventListener, useVModel } from '@vueuse/core';
|
import { useEventListener } from '@vueuse/core';
|
||||||
import { watch } from 'vue';
|
import { watch } from 'vue';
|
||||||
|
|
||||||
interface Props {
|
const open = defineModel('open', { default: false });
|
||||||
open: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Emit {
|
watch(open, value => {
|
||||||
(e: 'update:open', value: boolean): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
open: false,
|
|
||||||
});
|
|
||||||
const emit = defineEmits<Emit>();
|
|
||||||
|
|
||||||
const isOpen = useVModel(props, 'open', emit, {passive: true});
|
|
||||||
|
|
||||||
watch(isOpen, value => {
|
|
||||||
if (value) {
|
if (value) {
|
||||||
document.body.classList.add('overflow-hidden');
|
document.body.classList.add('overflow-hidden');
|
||||||
} else {
|
} else {
|
||||||
@@ -27,18 +14,18 @@ watch(isOpen, value => {
|
|||||||
});
|
});
|
||||||
useEventListener('keyup', e => {
|
useEventListener('keyup', e => {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
isOpen.value = false;
|
open.value = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Transition name="fade">
|
<Transition name="fade">
|
||||||
<template v-if="isOpen">
|
<template v-if="open">
|
||||||
<div class="fixed inset-0 z-10">
|
<div class="fixed inset-0 z-10">
|
||||||
<div class="absolute bg-black opacity-80 inset-0 z-0" />
|
<div class="absolute bg-black opacity-80 inset-0 z-0" />
|
||||||
<div class="absolute grid inset-0">
|
<div class="absolute grid inset-0">
|
||||||
<div class="justify-self-center m-auto" v-on-click-outside="() => isOpen = false">
|
<div class="justify-self-center m-auto" v-on-click-outside="() => open = false">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,24 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useVModel } from '@vueuse/core';
|
|
||||||
|
|
||||||
interface Props {
|
const modelValue = defineModel({ default: false });
|
||||||
modelValue?: boolean;
|
|
||||||
}
|
|
||||||
interface Emits {
|
|
||||||
(e: 'update:modelValue', value: boolean): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
modelValue: false
|
|
||||||
});
|
|
||||||
const emit = defineEmits<Emits>();
|
|
||||||
|
|
||||||
const value = useVModel(props, 'modelValue', emit);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<label class="flex items-center relative w-max cursor-pointer select-none">
|
<label class="flex items-center relative w-max cursor-pointer select-none">
|
||||||
<input type="checkbox" class="appearance-none transition-colors cursor-pointer w-10 h-5 rounded-full checked:bg-emerald-500 peer" v-model="value" />
|
<input type="checkbox" class="appearance-none transition-colors cursor-pointer w-10 h-5 rounded-full checked:bg-emerald-500 peer" v-model="modelValue" />
|
||||||
<span class="w-5 h-5 right-5 absolute rounded-full transform transition-transform bg-slate-100 peer-checked:bg-emerald-200" />
|
<span class="w-5 h-5 right-5 absolute rounded-full transform transition-transform bg-slate-100 peer-checked:bg-emerald-200" />
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,23 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { vElementHover } from '@vueuse/components';
|
import { vElementHover } from '@vueuse/components';
|
||||||
import { useElementBounding, useVModel } from '@vueuse/core';
|
import { useElementBounding } from '@vueuse/core';
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useSharedWindowSize } from './tooltip';
|
import { useSharedWindowSize } from './tooltip';
|
||||||
|
|
||||||
interface Props {
|
const open = defineModel('open', { default: false });
|
||||||
open: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Emit {
|
|
||||||
(e: 'update:open', value: boolean): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
open: false,
|
|
||||||
});
|
|
||||||
const emit = defineEmits<Emit>();
|
|
||||||
|
|
||||||
const isOpen = useVModel(props, 'open', emit, {passive: true});
|
|
||||||
|
|
||||||
const { width, height } = useSharedWindowSize();
|
const { width, height } = useSharedWindowSize();
|
||||||
const mainDiv = ref<HTMLDivElement | null>(null);
|
const mainDiv = ref<HTMLDivElement | null>(null);
|
||||||
@@ -39,16 +26,16 @@ const positions = computed(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div ref="mainDiv" clas="flex flex-col items-center justify-center" :class="{
|
<div ref="mainDiv" clas="flex flex-col items-center justify-center" :class="{
|
||||||
'open': isOpen,
|
'open': open,
|
||||||
'tooltip-top': positions.includes('top'),
|
'tooltip-top': positions.includes('top'),
|
||||||
'tooltip-bottom': positions.includes('bottom'),
|
'tooltip-bottom': positions.includes('bottom'),
|
||||||
'tooltip-left': positions.includes('left'),
|
'tooltip-left': positions.includes('left'),
|
||||||
'tooltip-right': positions.includes('right')
|
'tooltip-right': positions.includes('right')
|
||||||
}">
|
}">
|
||||||
<div v-element-hover="(h: boolean) => isOpen = h" class="m-auto header">
|
<div v-element-hover="(h: boolean) => open = h" class="m-auto header">
|
||||||
<slot name="header" />
|
<slot name="header" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isOpen" class="m-auto">
|
<div v-if="open" class="m-auto">
|
||||||
<div class="z-10 relative">
|
<div class="z-10 relative">
|
||||||
<div class="absolute">
|
<div class="absolute">
|
||||||
<slot />
|
<slot />
|
||||||
|
|||||||
@@ -1,25 +1,18 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { vOnClickOutside } from '@vueuse/components';
|
import { vOnClickOutside } from '@vueuse/components';
|
||||||
import { useVirtualList, useVModel } from '@vueuse/core';
|
import { useVirtualList } from '@vueuse/core';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import { nextTick, ref, watch, watchEffect } from 'vue';
|
import { nextTick, ref, watch, watchEffect } from 'vue';
|
||||||
import { MarketType, searchMarketTypes } from './MarketType';
|
import { MarketType, searchMarketTypes } from './MarketType';
|
||||||
import MarketTypeLabel from "./MarketTypeLabel.vue";
|
import MarketTypeLabel from "./MarketTypeLabel.vue";
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
modelValue?: MarketType;
|
|
||||||
}
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
(e: 'update:modelValue', value?: MarketType): void;
|
|
||||||
(e: 'submit'): void;
|
(e: 'submit'): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>();
|
const modelValue = defineModel<MarketType>();
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
const value = useVModel(props, 'modelValue', emit);
|
|
||||||
|
|
||||||
const isOpen = ref(false);
|
const isOpen = ref(false);
|
||||||
const name = ref('');
|
const name = ref('');
|
||||||
const suggestions = ref<MarketType[]>([]);
|
const suggestions = ref<MarketType[]>([]);
|
||||||
@@ -47,7 +40,7 @@ const moveUp = () => {
|
|||||||
}
|
}
|
||||||
const select = (type?: MarketType) => {
|
const select = (type?: MarketType) => {
|
||||||
log.debug('Select:', type);
|
log.debug('Select:', type);
|
||||||
value.value = type;
|
modelValue.value = type;
|
||||||
currentIndex.value = -1;
|
currentIndex.value = -1;
|
||||||
suggestions.value = [];
|
suggestions.value = [];
|
||||||
isOpen.value = false;
|
isOpen.value = false;
|
||||||
@@ -62,18 +55,18 @@ const submit = async () => {
|
|||||||
|
|
||||||
select(v);
|
select(v);
|
||||||
await nextTick();
|
await nextTick();
|
||||||
} else if (props.modelValue === undefined && suggestions.value.length > 0) {
|
} else if (modelValue.value === undefined && suggestions.value.length > 0) {
|
||||||
select(suggestions.value[0]);
|
select(suggestions.value[0]);
|
||||||
await nextTick();
|
await nextTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.value === undefined) {
|
if (modelValue.value === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit('submit');
|
emit('submit');
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => props.modelValue, async v => {
|
watch(() => modelValue.value, async v => {
|
||||||
if (v === undefined) {
|
if (v === undefined) {
|
||||||
name.value = '';
|
name.value = '';
|
||||||
} else {
|
} else {
|
||||||
@@ -96,7 +89,7 @@ watchEffect(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<div @click="() => isOpen = true" v-on-click-outside="() => isOpen = false">
|
<div @click="() => isOpen = true" v-on-click-outside="() => isOpen = false">
|
||||||
<div class="fake-input">
|
<div class="fake-input">
|
||||||
<img v-if="value?.id" :src="`https://images.evetech.net/types/${value.id}/icon?size=32`" alt="" />
|
<img v-if="modelValue?.id" :src="`https://images.evetech.net/types/${modelValue.id}/icon?size=32`" alt="" />
|
||||||
<input type="text" v-model="name" @keyup.enter="submit" @keyup.down="moveDown" @keyup.up="moveUp" />
|
<input type="text" v-model="name" @keyup.enter="submit" @keyup.down="moveDown" @keyup.up="moveUp" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="suggestions.length > 1" class="z-20 absolute w-96">
|
<div v-if="suggestions.length > 1" class="z-20 absolute w-96">
|
||||||
|
|||||||
@@ -1,24 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useVModel } from '@vueuse/core';
|
|
||||||
|
|
||||||
interface Props {
|
const modelValue = defineModel({ default: false });
|
||||||
modelValue?: boolean;
|
|
||||||
}
|
|
||||||
interface Emits {
|
|
||||||
(e: 'update:modelValue', value: boolean): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
modelValue: false
|
|
||||||
});
|
|
||||||
const emit = defineEmits<Emits>();
|
|
||||||
|
|
||||||
const value = useVModel(props, 'modelValue', emit);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<label class="flex items-center relative w-max cursor-pointer select-none">
|
<label class="flex items-center relative w-max cursor-pointer select-none">
|
||||||
<input type="checkbox" class="appearance-none transition-colors cursor-pointer w-14 h-7 rounded-full" v-model="value" />
|
<input type="checkbox" class="appearance-none transition-colors cursor-pointer w-14 h-7 rounded-full" v-model="modelValue" />
|
||||||
<span class="absolute font-medium text-xs right-1"> Buy </span>
|
<span class="absolute font-medium text-xs right-1"> Buy </span>
|
||||||
<span class="absolute font-medium text-xs right-8"> Sell </span>
|
<span class="absolute font-medium text-xs right-8"> Sell </span>
|
||||||
<span class="w-7 h-7 right-7 absolute rounded-full transform transition-transform bg-slate-100" />
|
<span class="w-7 h-7 right-7 absolute rounded-full transform transition-transform bg-slate-100" />
|
||||||
|
|||||||
@@ -1,22 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { evepraisalAxiosInstance } from '@/market/appraisal/evepraisal';
|
import { evepraisalAxiosInstance } from '@/market/appraisal/evepraisal';
|
||||||
import { useVModel } from '@vueuse/core';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
name: string;
|
name: string;
|
||||||
modelValue?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Emits {
|
const modelValue = defineModel({ default: '' });
|
||||||
(e: 'update:modelValue', value: string): void;
|
defineProps<Props>();
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
modelValue: ''
|
|
||||||
});
|
|
||||||
const emit = defineEmits<Emits>();
|
|
||||||
|
|
||||||
const value = useVModel(props, 'modelValue', emit);
|
|
||||||
|
|
||||||
const loadFromId = async (e: Event) => {
|
const loadFromId = async (e: Event) => {
|
||||||
const input = e.target as HTMLInputElement;
|
const input = e.target as HTMLInputElement;
|
||||||
@@ -31,7 +21,7 @@ const loadFromId = async (e: Event) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
value.value = JSON.stringify(response.data);
|
modelValue.value = JSON.stringify(response.data);
|
||||||
input.value = '';
|
input.value = '';
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -39,6 +29,6 @@ const loadFromId = async (e: Event) => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex-1 mx-1">
|
<div class="flex-1 mx-1">
|
||||||
<span>{{ name }}</span><input type="text" class="ms-2" @change="loadFromId" placeholder="id evepraisal" />
|
<span>{{ name }}</span><input type="text" class="ms-2" @change="loadFromId" placeholder="id evepraisal" />
|
||||||
<textarea class="mt-1" v-model="value" />
|
<textarea class="mt-1" v-model="modelValue" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
Reference in New Issue
Block a user