Browse Source

refactor(AutoSuggest): Converted to composition API

Owen Diffey 2 years ago
parent
commit
52ed0c16db
2 changed files with 98 additions and 110 deletions
  1. 73 86
      frontend/src/components/AutoSuggest.vue
  2. 25 24
      frontend/src/components/FloatingBox.vue

+ 73 - 86
frontend/src/components/AutoSuggest.vue

@@ -1,3 +1,76 @@
+<script setup lang="ts">
+import { ref, computed } from "vue";
+
+const props = defineProps({
+	modelValue: { type: String, default: "" },
+	placeholder: { type: String, default: "Search value" },
+	disabled: { type: Boolean, default: false },
+	allItems: { type: Array, default: () => [] }
+});
+
+const emit = defineEmits(["update:modelValue"]);
+
+const inputFocussed = ref(false);
+const containerFocussed = ref(false);
+const itemFocussed = ref(false);
+const keydownInputTimeout = ref();
+const items = ref([]);
+
+const value = computed({
+	get: () => props.modelValue,
+	set: value => emit("update:modelValue", value)
+});
+
+const blurInput = event => {
+	if (
+		event.relatedTarget &&
+		event.relatedTarget.classList.contains("autosuggest-item")
+	)
+		itemFocussed.value = true;
+	inputFocussed.value = false;
+};
+
+const focusInput = () => {
+	inputFocussed.value = true;
+};
+
+const keydownInput = () => {
+	clearTimeout(keydownInputTimeout.value);
+	keydownInputTimeout.value = setTimeout(() => {
+		if (value.value && value.value.length > 1) {
+			items.value = props.allItems.filter(item =>
+				item.toLowerCase().startsWith(value.value.toLowerCase())
+			);
+		} else items.value = [];
+	}, 1000);
+};
+
+const focusAutosuggestContainer = () => {
+	containerFocussed.value = true;
+};
+
+const blurAutosuggestContainer = () => {
+	containerFocussed.value = false;
+};
+
+const selectAutosuggestItem = item => {
+	value.value = item;
+	items.value = [];
+};
+
+const focusAutosuggestItem = () => {
+	itemFocussed.value = true;
+};
+
+const blurAutosuggestItem = event => {
+	if (
+		!event.relatedTarget ||
+		!event.relatedTarget.classList.contains("autosuggest-item")
+	)
+		itemFocussed.value = false;
+};
+</script>
+
 <template>
 	<div>
 		<input
@@ -36,92 +109,6 @@
 	</div>
 </template>
 
-<script>
-export default {
-	props: {
-		modelValue: {
-			type: String,
-			default: ""
-		},
-		placeholder: {
-			type: String,
-			default: "Search value"
-		},
-		disabled: {
-			type: Boolean,
-			default: false
-		},
-		allItems: {
-			type: Array,
-			default: () => []
-		}
-	},
-	emits: ["update:modelValue"],
-	data() {
-		return {
-			inputFocussed: false,
-			containerFocussed: false,
-			itemFocussed: false,
-			keydownInputTimeout: null,
-			items: []
-		};
-	},
-	computed: {
-		value: {
-			get() {
-				return this.modelValue;
-			},
-			set(value) {
-				this.$emit("update:modelValue", value);
-			}
-		}
-	},
-	methods: {
-		blurInput(event) {
-			if (
-				event.relatedTarget &&
-				event.relatedTarget.classList.contains("autosuggest-item")
-			)
-				this.itemFocussed = true;
-			this.inputFocussed = false;
-		},
-		focusInput() {
-			this.inputFocussed = true;
-		},
-		keydownInput() {
-			clearTimeout(this.keydownInputTimeout);
-			this.keydownInputTimeout = setTimeout(() => {
-				if (this.value && this.value.length > 1) {
-					this.items = this.allItems.filter(item =>
-						item.toLowerCase().startsWith(this.value.toLowerCase())
-					);
-				} else this.items = [];
-			}, 1000);
-		},
-		focusAutosuggestContainer() {
-			this.containerFocussed = true;
-		},
-		blurAutosuggestContainer() {
-			this.containerFocussed = false;
-		},
-		selectAutosuggestItem(item) {
-			this.value = item;
-			this.items = [];
-		},
-		focusAutosuggestItem() {
-			this.itemFocussed = true;
-		},
-		blurAutosuggestItem(event) {
-			if (
-				!event.relatedTarget ||
-				!event.relatedTarget.classList.contains("autosuggest-item")
-			)
-				this.itemFocussed = false;
-		}
-	}
-};
-</script>
-
 <style lang="less" scoped>
 .night-mode .autosuggest-container {
 	background-color: var(--dark-grey) !important;

+ 25 - 24
frontend/src/components/FloatingBox.vue

@@ -27,27 +27,6 @@ const saveDebounceTimeout = ref();
 const resizeDebounceTimeout = ref();
 const shown = ref(false);
 
-onMounted(async () => {
-	let initial = {
-		top: 10,
-		left: 10,
-		width: 200,
-		height: 400
-	};
-	if (props.id !== null && localStorage[`box:${props.id}`]) {
-		const json = JSON.parse(localStorage.getItem(`box:${props.id}`));
-		initial = { ...initial, ...json };
-		shown.value = json.shown;
-	} else {
-		initial.top =
-			props.initial === "align-bottom"
-				? Math.max(document.body.clientHeight - 10 - initial.height, 0)
-				: 10;
-	}
-	setInitialBox(initial, true);
-	resetBoxPosition(true);
-});
-
 const saveBox = () => {
 	if (saveDebounceTimeout.value) clearTimeout(saveDebounceTimeout.value);
 
@@ -139,13 +118,35 @@ const onWindowResize = () => {
 onWindowResize();
 window.addEventListener("resize", onWindowResize);
 
-onDragBoxUpdate.value = () => {
-	onWindowResize();
-};
+onMounted(async () => {
+	let initial = {
+		top: 10,
+		left: 10,
+		width: 200,
+		height: 400
+	};
+	if (props.id !== null && localStorage[`box:${props.id}`]) {
+		const json = JSON.parse(localStorage.getItem(`box:${props.id}`));
+		initial = { ...initial, ...json };
+		shown.value = json.shown;
+	} else {
+		initial.top =
+			props.initial === "align-bottom"
+				? Math.max(document.body.clientHeight - 10 - initial.height, 0)
+				: 10;
+	}
+	setInitialBox(initial, true);
+	resetBoxPosition(true);
+
+	onDragBoxUpdate.value = () => {
+		onWindowResize();
+	};
+});
 
 onUnmounted(() => {
 	window.removeEventListener("resize", onWindowResize);
 	if (resizeDebounceTimeout.value) clearTimeout(resizeDebounceTimeout.value);
+	if (saveDebounceTimeout.value) clearTimeout(saveDebounceTimeout.value);
 });
 
 defineExpose({