]> git.immae.eu Git - github/bastienwirtz/homer.git/blob - src/components/SearchInput.vue
Merge branch 'bastienwirtz:main' into hotkey
[github/bastienwirtz/homer.git] / src / components / SearchInput.vue
1 <template>
2 <div class="search-bar">
3 <label for="search" class="search-label"></label>
4 <input
5 type="text"
6 ref="search"
7 :value="value"
8 @input="search($event.target.value)"
9 @keyup.enter.exact="open()"
10 @keyup.alt.enter="open('_blank')"
11 />
12 </div>
13 </template>
14
15 <script>
16 export default {
17 name: "SearchInput",
18 props: {
19 value: String,
20 hotkey: {
21 type: String,
22 default: "/"
23 }
24 },
25 mounted() {
26 this._keyListener = function (event) {
27 if (event.key === this.hotkey) {
28 event.preventDefault();
29 this.focus();
30 }
31 if (event.key === "Escape") {
32 this.cancel();
33 }
34 };
35 document.addEventListener("keydown", this._keyListener.bind(this));
36
37 // fill search from get parameter.
38 const search = new URLSearchParams(window.location.search).get("search");
39 if (search) {
40 this.$refs.search.value = search;
41 this.search(search);
42 this.focus();
43 }
44 },
45 methods: {
46 open: function (target = null) {
47 if (!this.$refs.search.value) {
48 return;
49 }
50 this.$emit("search-open", target);
51 },
52 focus: function () {
53 this.$emit("search-focus");
54 this.$nextTick(() => {
55 this.$refs.search.focus();
56 });
57 },
58 setSearchURL: function (value) {
59 const url = new URL(window.location);
60 if (value === "") {
61 url.searchParams.delete("search");
62 } else {
63 url.searchParams.set("search", value);
64 }
65 window.history.replaceState("search", null, url);
66 },
67 cancel: function () {
68 this.setSearchURL("");
69 this.$refs.search.value = "";
70 this.$refs.search.blur();
71 this.$emit("search-cancel");
72 },
73 search: function (value) {
74 this.setSearchURL(value);
75 this.$emit("input", value.toLowerCase());
76 },
77 },
78 beforeDestroy() {
79 document.removeEventListener("keydown", this._keyListener);
80 },
81 };
82 </script>
83
84 <style lang="scss" scoped></style>