styling; edit existing modal

This commit is contained in:
Egor Aristov 2025-02-04 15:23:39 +03:00
parent aca243cef7
commit 57a2af04d3
4 changed files with 140 additions and 12 deletions

View File

@ -1,17 +1,20 @@
<script setup lang="ts">
const {active} = defineProps({
active: Boolean
active: {
type: Boolean,
default: true
}
});
</script>
<template>
<div class="wrapper" :class="{active: active}">
<div class="btn-wrapper" :class="{active: active}">
<slot></slot>
</div>
</template>
<style scoped lang="scss">
div.wrapper {
div.btn-wrapper {
display: inline-block;
border-radius: 4px;
margin: 4px 8px 0 0;

View File

@ -0,0 +1,91 @@
<script setup lang="ts">
import Field from "@/components/Field.vue";
import {type Field as FieldSpec} from "@/urlmaker/specs";
import {validateUrl} from "@/urlmaker/validators.ts";
import Btn from "@/components/Btn.vue";
import {onMounted, onUnmounted, ref, watch} from "vue";
const field: FieldSpec = {
name: '',
input_type: 'url',
label: 'URL of feed for editing',
default: '',
required: true,
validate: validateUrl,
}
const {visible, modelValue} = defineProps({
visible: Boolean,
modelValue: {
type: String,
required: true,
}
});
const emit = defineEmits(['close', 'update:modelValue']);
const url = ref(modelValue);
watch(() => visible, () => {
url.value = modelValue;
});
const valid = ref(false);
watch(url, (value) => {
valid.value = field.validate(value).ok;
});
const accept = () => {
valid.value = field.validate(url.value).ok;
if (valid.value) {
emit('update:modelValue', url.value);
emit('close');
}
}
const listener = (e: KeyboardEvent) => {
if (e.code === 'Escape') emit('close');
if (e.code === 'Enter') accept();
};
onMounted(() => {
document.addEventListener('keyup', listener);
});
onUnmounted(() => {
document.removeEventListener('keyup', listener);
});
</script>
<template>
<Teleport to="#app">
<div class="modal-wrapper" v-if="visible" @click="$emit('close')">
<div class="modal" @click.stop>
<Field :field="field" v-model="url" :focused="true"/>
<Btn :active="valid" @click="accept">Edit</Btn>
</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

@ -1,20 +1,26 @@
<script setup lang="ts">
import type {Field} from "@/urlmaker/specs.ts";
import {getCurrentInstance} from "vue";
import {getCurrentInstance, onMounted, useTemplateRef} from "vue";
defineProps<{
field: Field
const {field, focused} = defineProps<{
field: Field,
focused: boolean,
}>();
const id = 'field' + getCurrentInstance()?.uid;
const model = defineModel();
const inputRef = useTemplateRef('field');
onMounted(() => {
if(focused) inputRef.value?.focus();
})
</script>
<template>
<div class="field">
<div class="label"><label :for="id">{{ field.label }}</label></div>
<div class="input">
<input :type="field.input_type" :name="field.name" :id="id" v-model="model"/>
<input :type="field.input_type" :name="field.name" :id="id" v-model="model" ref="field"/>
</div>
</div>
</template>
@ -23,4 +29,17 @@ const model = defineModel();
div.field {
margin: 0 0 8px 0;
}
div.label {
font-size: 0.9em;
}
div.input {
margin: 2px 0 0 0;
box-sizing: border-box;
input {
box-sizing: border-box;
width: 100%;
padding: 2px;
}
}
</style>

View File

@ -4,6 +4,7 @@ import {reactive, ref, watch} from "vue";
import {type Field, fields, type Specs} from "@/urlmaker/specs.ts";
import Btn from "@/components/Btn.vue";
import Copyable from "@/components/Copyable.vue";
import EditUrlModal from "@/components/EditUrlModal.vue";
const emptySpecs = fields.reduce((o, f) => {
o[f.name] = f.default;
@ -18,21 +19,35 @@ watch(specs, (value, oldValue) => {
));
});
const link = ref("https://kek.com");
const existingLink = ref("");
const link = ref("");
const editModalVisible = ref(false);
</script>
<template>
<SpecsForm v-model="specs" class="specs-form"></SpecsForm>
<Btn :active="formValid">Generate link</Btn>
<Btn :active="formValid">Screenshot</Btn>
<Copyable v-if="link" :contents="link" class="link-view"></Copyable>
<div class="wrapper">
<SpecsForm v-model="specs" class="specs-form"></SpecsForm>
<Btn :active="formValid">Generate link</Btn>
<Btn :active="formValid">Screenshot</Btn>
<Btn @click="editModalVisible = true">Edit existing task</Btn>
<Copyable v-if="link" :contents="link" class="link-view"></Copyable>
<EditUrlModal :visible="editModalVisible" @close="editModalVisible = false"
v-model="existingLink"></EditUrlModal>
</div>
</template>
<style scoped lang="scss">
div.wrapper {
width: 100%;
max-width: 600px;
margin: auto;
}
.specs-form {
margin-bottom: 15px;
}
.link-view {
margin-top: 15px !important;
}