<template>\r
<div class="container mx-auto flex h-screen flex-col px-2 py-4">\r
<PrimeToast />\r
- <SearchModal ref="searchModal" />\r
+ <SearchModal v-model="isSearchModalVisible" />\r
<NavBar\r
v-if="showNavBar"\r
ref="navBar"\r
import { computed, ref } from "vue";\r
import { RouterView, useRoute } from "vue-router";\r
\r
-import { getConfig, apiErrorHandler } from "./api.js";\r
+import { apiErrorHandler, getConfig } from "./api.js";\r
import PrimeToast from "./components/PrimeToast.vue";\r
import { useGlobalStore } from "./globalStore.js";\r
import { loadTheme } from "./helpers.js";\r
import { loadStoredToken } from "./tokenStorage.js";\r
\r
const globalStore = useGlobalStore();\r
+const isSearchModalVisible = ref(false);\r
const navBar = ref();\r
const route = useRoute();\r
-const searchModal = ref();\r
const toast = useToast();\r
\r
// '/' to search\r
});\r
\r
function toggleSearchModal() {\r
- searchModal.value.toggle();\r
+ isSearchModalVisible.value = !isSearchModalVisible.value;\r
}\r
\r
loadTheme();\r
<template>
<Modal
- ref="modal"
+ v-model="isVisible"
:title="title"
:class="{ 'border border-l-4 border-l-theme-danger': isDanger }"
:closeHandler="cancelHandler"
<!-- Buttons -->
<div class="flex justify-end">
<CustomButton label="Cancel" @click="cancelHandler" class="mr-2" />
- <CustomButton :label="confirmButtonText" @click="confirmHandler" danger />
+ <CustomButton
+ v-focus
+ :label="confirmButtonText"
+ @click="confirmHandler"
+ danger
+ />
</div>
</Modal>
</template>
<script setup>
-import { ref } from "vue";
-
import CustomButton from "./CustomButton.vue";
import Modal from "./Modal.vue";
isDanger: Boolean,
});
const emit = defineEmits(["confirm", "cancel"]);
-
-const modal = ref();
-
-function toggle() {
- modal.value.toggle();
-}
+const isVisible = defineModel({ type: Boolean });
function cancelHandler() {
- modal.value.setVisibility(false);
+ isVisible.value = false;
emit("cancel");
}
function confirmHandler() {
- modal.value.setVisibility(false);
+ isVisible.value = false;
emit("confirm");
}
-
-defineExpose({ toggle });
</script>
<div
class="relative max-w-[500px] grow rounded-lg border border-theme-border bg-theme-background px-6 py-4 shadow-lg"
:class="$attrs.class"
+ @keyup.esc="close"
>
<CustomButton
v-if="props.showClose"
:iconPath="mdiWindowClose"
- @click="close"
+ @click="closeHandler"
class="absolute right-1 top-1"
/>
<!-- Title -->
<script setup>
import { mdiWindowClose } from "@mdi/js";
-import { ref } from "vue";
import CustomButton from "./CustomButton.vue";
defineOptions({
inheritAttrs: false,
});
-
const props = defineProps({
title: { type: String, default: "Confirm" },
showClose: { type: Boolean },
- closeHandler: Function,
- modalClasses: String,
+ closeHandlerOverride: Function,
});
+const isVisible = defineModel({ type: Boolean });
-const isVisible = ref(false);
-
-function toggle() {
- isVisible.value = !isVisible.value;
-}
-
-function setVisibility(value) {
- isVisible.value = value;
-}
-
-function close() {
- if (props.closeHandler) {
- props.closeHandler();
+function closeHandler() {
+ if (props.closeHandlerOverride) {
+ props.closeHandlerOverride();
} else {
- setVisibility(false);
+ isVisible.value = false;
}
}
-
-defineExpose({ toggle, setVisibility });
</script>
app.use(pinia);\r
app.use(PrimeVue, { unstyled: true });\r
app.use(ToastService);\r
+\r
+// Custom v-focus directive to focus on an element when mounted\r
+app.directive("focus", {\r
+ mounted(el) {\r
+ el.focus();\r
+ },\r
+});\r
+\r
app.mount("#app");\r
<form class="flex w-full" @submit.prevent="search">
<TextInput
v-model="searchTerm"
+ v-focus
:placeholder="props.hidePlaceholder ? '' : 'Search'"
class="rounded-r-none"
- ref="textInput"
/>
<CustomButton
:iconPath="mdilMagnify"
<script setup>
import { mdilMagnify } from "@mdi/light-js";
import { useToast } from "primevue/usetoast";
-import { onMounted, ref } from "vue";
+import { ref } from "vue";
import { useRouter } from "vue-router";
import * as constants from "../constants";
const emit = defineEmits(["search"]);
const router = useRouter();
-const textInput = ref();
const searchTerm = ref(props.initialSearchTerm);
const toast = useToast();
toast.add(getToastOptions("Error", "Please enter a search term.", true));
}
}
-
-onMounted(() => {
- textInput.value.focus();
-});
</script>
<template>
- <Modal ref="modal" title="Search">
+ <Modal v-model="isVisible" title="Search">
<SearchInput @search="toggle" class="mb-4" hidePlaceholder />
<div class="flex justify-end">
- <CustomButton label="Close" @click="toggle" />
+ <CustomButton label="Close" @click="toggleHandler" />
</div>
</Modal>
</template>
<script setup>
-import { ref } from "vue";
-
import CustomButton from "../components/CustomButton.vue";
import Modal from "../components/Modal.vue";
import SearchInput from "./SearchInput.vue";
-const modal = ref();
+const isVisible = defineModel({ type: Boolean });
-function toggle() {
- modal.value.toggle();
+function toggleHandler() {
+ isVisible.value = !isVisible.value;
}
-
-defineExpose({ toggle });
</script>
<template>
<!-- Confirm Deletion Modal -->
<ConfirmModal
- ref="deleteConfirmModal"
+ v-model="isDeleteModalVisible"
title="Confirm Deletion"
:message="`Are you sure you want to delete the note '${note.title}'?`"
confirmButtonText="Delete"
});
const editMode = ref(false);
-const deleteConfirmModal = ref();
+const isDeleteModalVisible = ref(false);
const isNewNote = computed(() => !props.title);
const loadingIndicator = ref();
const note = ref({});
}
function deleteHandler() {
- deleteConfirmModal.value.toggle();
+ isDeleteModalVisible.value = true;
}
function deleteConfirmedHandler() {