move modal to another component

This commit is contained in:
Egor Aristov 2025-02-22 22:47:28 +03:00
parent 21b5774e9e
commit e477f8fc91
Signed by: egor3f
GPG Key ID: 40482A264AAEC85F
3 changed files with 48 additions and 37 deletions

View File

@ -5,6 +5,7 @@ import {type Field as FieldSpec} from "@/urlmaker/specs";
import {validateUrl} from "@/urlmaker/validators.ts"; import {validateUrl} from "@/urlmaker/validators.ts";
import Btn from "@/components/Btn.vue"; import Btn from "@/components/Btn.vue";
import {onMounted, onUnmounted, ref, watch} from "vue"; import {onMounted, onUnmounted, ref, watch} from "vue";
import Modal from "@/components/Modal.vue";
const field: FieldSpec = { const field: FieldSpec = {
name: '', name: '',
@ -15,18 +16,17 @@ const field: FieldSpec = {
validate: validateUrl, validate: validateUrl,
} }
const {visible, modelValue} = defineProps({ const visible = defineModel('visible');
visible: Boolean, const {modelValue} = defineProps({
modelValue: { modelValue: {
type: String, type: String,
required: true, required: true,
} }
}); });
const emit = defineEmits(['update:modelValue', 'update:visible']);
const emit = defineEmits(['close', 'update:modelValue']);
const url = ref(modelValue); const url = ref(modelValue);
watch(() => visible, () => { watch(visible, () => {
url.value = modelValue; url.value = modelValue;
}); });
@ -39,12 +39,12 @@ const accept = () => {
valid.value = field.validate(url.value).ok; valid.value = field.validate(url.value).ok;
if (valid.value) { if (valid.value) {
emit('update:modelValue', url.value); emit('update:modelValue', url.value);
emit('close'); emit('update:visible', false);
} }
} }
const listener = (e: KeyboardEvent) => { const listener = (e: KeyboardEvent) => {
if (e.code === 'Escape') emit('close'); if (e.code === 'Escape') emit('update:visible', false);
if (e.code === 'Enter') accept(); if (e.code === 'Enter') accept();
}; };
onMounted(() => { onMounted(() => {
@ -57,35 +57,12 @@ onUnmounted(() => {
</script> </script>
<template> <template>
<Teleport to="#app"> <Modal v-model="visible">
<div class="modal-wrapper" v-if="visible" @click="$emit('close')">
<div class="modal" @click.stop>
<Field :field="field" v-model="url" :focused="true"/> <Field :field="field" v-model="url" :focused="true"/>
<Btn :active="valid" @click="accept">Edit</Btn> <Btn :active="valid" @click="accept">Edit</Btn>
</div> </Modal>
</div>
</Teleport>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
div.modal-wrapper {
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
display: flex;
background: rgba(200, 200, 200, 0.5);
backdrop-filter: blur(2px);
}
div.modal {
width: 100%;
max-width: 400px;
margin: auto auto;
background: #ffffff;
padding: 10px;
border-radius: 6px;
box-shadow: #a0a0a0 1px 2px 2px;
}
</style> </style>

View File

@ -0,0 +1,36 @@
<script setup lang="ts">
const visible = defineModel();
</script>
<template>
<Teleport to="#app">
<div class="modal-wrapper" v-if="visible" @click="visible = false">
<div class="modal" @click.stop>
<slot></slot>
</div>
</div>
</Teleport>
</template>
<style scoped lang="scss">
div.modal-wrapper {
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
display: flex;
background: rgba(200, 200, 200, 0.5);
backdrop-filter: blur(2px);
}
div.modal {
width: 100%;
max-width: 400px;
margin: auto auto;
background: #ffffff;
padding: 10px;
border-radius: 6px;
box-shadow: #a0a0a0 1px 2px 2px;
}
</style>

View File

@ -18,7 +18,6 @@ watch(existingLink, async (value) => {
existingLink.value = ""; existingLink.value = "";
try { try {
store.updateSpecs(await decodeUrl(value)); store.updateSpecs(await decodeUrl(value));
link.value = "";
} catch (e) { } catch (e) {
console.log(e); console.log(e);
alert(`Decoding error: ${e}`); alert(`Decoding error: ${e}`);
@ -58,8 +57,7 @@ function screenshot() {
<Btn @click="editModalVisible = true">Edit existing task</Btn> <Btn @click="editModalVisible = true">Edit existing task</Btn>
<Btn @click="store.reset">Reset Form</Btn> <Btn @click="store.reset">Reset Form</Btn>
<Copyable v-if="link" :contents="link" class="link-view"></Copyable> <Copyable v-if="link" :contents="link" class="link-view"></Copyable>
<EditUrlModal :visible="editModalVisible" @close="editModalVisible = false" <EditUrlModal v-model:visible="editModalVisible" v-model="existingLink"></EditUrlModal>
v-model="existingLink"></EditUrlModal>
</div> </div>
</template> </template>