Skip to content

Commit 4362f5a

Browse files
committed
Search for mobile and mobile menu styles.
1 parent fd4c976 commit 4362f5a

File tree

3 files changed

+105
-61
lines changed

3 files changed

+105
-61
lines changed

src/components/header/header-actions.astro

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ const { mobile = false }: Props = Astro.props;
1414
const IS_LIVE = false;
1515
---
1616

17-
<div class="flex items-center justify-end gap-2 h-[85px]">
17+
<div class="flex items-start justify-end gap-2 h-[85px]">
1818
<Search />
19-
<div class="ml-auto flex items-center ">
19+
<div class="ml-auto flex items-start">
2020
{
21-
!mobile ?
21+
!mobile ?
2222
<>
23-
<Button id="searchButton" icon="search" iconSize="fa-xl" clear ></Button>
23+
<Button id="searchButton" icon="search" iconSize="fa-xl" clear title="Search (Crtl+K)"></Button>
2424
<Button url="/tickets" icon="ticket" class="max-xl:hidden">Register Now!</Button>
2525
{IS_LIVE && <Button url="/live">Live</Button>}
2626
</>

src/components/search/Search.astro

Lines changed: 93 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
import Search2 from "astro-pagefind/components/Search";
33
import Button from "@ui/Button.astro";
4+
import HeaderLogo from "@components/header/header-logo.astro";
45
---
56

67
<div class="search-wrapper hidden" style="display: none;">
@@ -15,7 +16,11 @@ import Button from "@ui/Button.astro";
1516
},
1617
}}
1718
/>
18-
<Button secondary icon="close" iconSize="fa-xl" class="search-wrapper-close w-[3em] h-[3em] " />
19+
20+
<div class="logo-wrapper">
21+
<HeaderLogo />
22+
</div>
23+
<Button secondary icon="close" iconSize="fa-xl" class="search-wrapper-close w-[3em] h-[3em] " />
1924
</div>
2025

2126
<style is:global>
@@ -30,7 +35,7 @@ import Button from "@ui/Button.astro";
3035
right: 0;
3136
z-index: 500;
3237
box-sizing: border-box;
33-
padding: 2rem;
38+
/*padding: 2rem;*/
3439
display: none;
3540
transition: opacity ease-out 0.2s;
3641
/*pointer-events: none;*/
@@ -41,22 +46,31 @@ import Button from "@ui/Button.astro";
4146
#search {
4247
padding:10px;
4348
position: relative;
44-
top: calc(3rem + 4vw);
49+
top: calc(5rem + 4vw);
4550
max-height: 80vh;
4651
width: 100%;
4752
max-width: calc(64rem + 8vw);
4853
margin: auto;
49-
background: #FFF;
50-
border-radius: 4px;
51-
box-shadow: 0 8px 24px -2px rgba(0,0,0,0.4);
54+
/*background: #FFF;*/
55+
/*border-radius: 4px;*/
56+
/*box-shadow: 0 8px 24px -2px rgba(0,0,0,0.4);*/
5257
overflow: auto;
5358
}
5459

5560
.search-wrapper-close {
5661
position: absolute;
5762
right: 0;
5863
top: 0;
59-
margin: 40px 24px;
64+
margin: 24px;
65+
border: 0;
66+
transition: opacity ease-out 0.2s;
67+
z-index: 10;
68+
}
69+
.logo-wrapper {
70+
position: absolute;
71+
left: 0;
72+
top: 0;
73+
margin: 24px;
6074
border: 0;
6175
transition: opacity ease-out 0.2s;
6276
z-index: 10;
@@ -65,65 +79,88 @@ import Button from "@ui/Button.astro";
6579
</style>
6680

6781
<script>
68-
import type { HTMLElementType } from "react";
69-
70-
document.addEventListener("DOMContentLoaded", function () {
71-
const searchContainer = document.querySelector(".pagefind-ui");
72-
const searchInput = searchContainer?.querySelector("input");
73-
let selectedIndex = -1;
74-
75-
function updateSelection() {
76-
const results = searchContainer?.querySelectorAll(".pagefind-ui__result");
77-
if (!results) return;
78-
79-
results.forEach((result, index) => {
80-
if (index === selectedIndex) {
81-
result.classList.add("selected");
82-
result.scrollIntoView({ block: "nearest", behavior: "smooth" });
83-
} else {
84-
result.classList.remove("selected");
85-
}
86-
});
87-
}
82+
document.addEventListener("DOMContentLoaded", function () {
83+
const searchWrapper = document.querySelector(".search-wrapper") as HTMLElement;
84+
const searchContainer = document.querySelector(".pagefind-ui");
85+
const searchInput = searchContainer?.querySelector("input");
86+
const closeButton = document.querySelector(".search-wrapper-close");
87+
let selectedIndex = -1;
8888

89-
document.addEventListener("keydown", function (event) {
90-
if (!searchContainer || !searchInput) return;
91-
92-
const results = searchContainer.querySelectorAll(".pagefind-ui__result");
93-
if (document.activeElement === searchInput) {
94-
if (event.key === "ArrowDown") {
95-
event.preventDefault();
96-
selectedIndex = (selectedIndex + 1) % results.length;
97-
updateSelection();
98-
} else if (event.key === "ArrowUp") {
99-
event.preventDefault();
100-
selectedIndex = (selectedIndex - 1 + results.length) % results.length;
101-
updateSelection();
102-
} else if (event.key === "Enter" && selectedIndex >= 0) {
103-
event.preventDefault();
104-
results[selectedIndex].querySelector("a")?.click();
105-
}
106-
}
107-
});
89+
function openSearch() {
90+
if (searchWrapper) {
91+
searchWrapper.style.display = "block";
92+
searchInput?.focus();
93+
}
94+
}
10895

109-
// Reset selection when the search query changes
110-
searchInput?.addEventListener("input", function () {
96+
function closeSearch() {
97+
if (searchWrapper) {
98+
searchWrapper.style.display = "none";
11199
selectedIndex = -1;
100+
}
101+
}
102+
103+
function updateSelection() {
104+
const results = searchContainer?.querySelectorAll(".pagefind-ui__result");
105+
if (!results) return;
106+
107+
results.forEach((result, index) => {
108+
if (index === selectedIndex) {
109+
result.classList.add("selected");
110+
result.scrollIntoView({ block: "nearest", behavior: "smooth" });
111+
} else {
112+
result.classList.remove("selected");
113+
}
112114
});
115+
}
113116

117+
document.addEventListener("keydown", function (event) {
118+
if (!searchContainer || !searchInput) return;
114119

115-
// Close button functionality
116-
const closeButton = document.querySelector(".search-wrapper-close");
117-
const searchWrapper = document.querySelector(".search-wrapper") as HTMLElement;
120+
const results = searchContainer.querySelectorAll(".pagefind-ui__result");
118121

119-
// Close button functionality - toggle display property
120-
closeButton?.addEventListener("click", function () {
121-
if (searchWrapper) {
122-
searchWrapper.style.display = searchWrapper.style.display === "none" ? "block" : "none";
122+
if (event.ctrlKey && event.key === "k") {
123+
event.preventDefault();
124+
openSearch();
125+
} else if (event.key === "Escape") {
126+
closeSearch();
127+
} else if (document.activeElement === searchInput) {
128+
if (event.key === "ArrowDown") {
129+
event.preventDefault();
130+
selectedIndex = (selectedIndex + 1) % results.length;
131+
updateSelection();
132+
} else if (event.key === "ArrowUp") {
133+
event.preventDefault();
134+
selectedIndex = (selectedIndex - 1 + results.length) % results.length;
135+
updateSelection();
136+
} else if (event.key === "Enter") {
137+
event.preventDefault();
138+
if (results.length > 0) {
139+
const indexToOpen = selectedIndex === -1 ? 0 : selectedIndex;
140+
results[indexToOpen]?.querySelector("a")?.click();
141+
}
123142
}
124-
});
143+
}
144+
});
125145

146+
// Highlight first result after results are injected
147+
const resultsObserver = new MutationObserver(() => {
148+
const results = searchContainer?.querySelectorAll(".pagefind-ui__result");
149+
if (results && results.length > 0) {
150+
selectedIndex = 0;
151+
updateSelection();
152+
}
126153
});
154+
155+
if (searchContainer) {
156+
resultsObserver.observe(searchContainer, {
157+
childList: true,
158+
subtree: true,
159+
});
160+
}
161+
162+
closeButton?.addEventListener("click", closeSearch);
163+
});
127164
</script>
128165
<style is:global>
129166
.modal__overlay {

src/components/ui/Button.astro

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ const {
1313
icon,
1414
iconSvg = false,
1515
iconRight = true,
16-
iconSize = ""
16+
iconSize = "",
17+
title="",
1718
} = Astro.props;
1819
1920
const resolvedIsExternal = isExternal ?? url?.startsWith("http");
@@ -26,13 +27,17 @@ const outlineClasses = "border-gray-500 text-gray-700 hover:bg-gray-100 hover:bg
2627
const disabledClasses = "opacity-50 pointer-events-none";
2728
const iconClasses = "mx-2 ";
2829
const idName = id;
30+
const slotContent = await Astro.slots.render('default')
31+
2932
3033
---
3134

3235
{url ? (
3336
<a
3437
id={idName}
3538
href={disabled ? undefined : url}
39+
title={title}
40+
aria-label={title ? title : slotContent }
3641
class={`${baseClasses}
3742
${clear ? clearClasses : outline ? outlineClasses : secondary ? secondaryClasses : primaryClasses}
3843
${disabled ? disabledClasses : ""}
@@ -48,6 +53,8 @@ const idName = id;
4853
) : (
4954
<button
5055
id={idName}
56+
title={title}
57+
aria-label={title ? title : slotContent }
5158
class={`${baseClasses}
5259
${clear ? clearClasses : outline ? outlineClasses : secondary ? secondaryClasses : primaryClasses}
5360
${disabled ? disabledClasses : ""}

0 commit comments

Comments
 (0)