website/src/components/gallery/ShowcaseTemplateSearch/index.tsx (175 lines of code) (raw):
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import React, { useState, useEffect } from "react";
import { SearchBox } from "@fluentui/react/lib/SearchBox";
import ExecutionEnvironment from "@docusaurus/ExecutionEnvironment";
import { useHistory, useLocation } from "@docusaurus/router";
import { Text, Link as FluentUILink } from "@fluentui/react-components";
import styles from "./styles.module.css";
import useBaseUrl from "@docusaurus/useBaseUrl";
import { useColorMode } from "@docusaurus/theme-common";
const TITLE = "Template Library";
const DESCRIPTION =
"An open-source template gallery to get started with Azure.";
const ADD_URL = "https://aka.ms/azd";
export var InputValue: string | null = null;
export type UserState = {
scrollTopPosition: number;
focusedElementId: string | undefined;
};
function prepareUserState(): UserState | undefined {
if (ExecutionEnvironment.canUseDOM) {
return {
scrollTopPosition: window.scrollY,
focusedElementId: document.activeElement?.id,
};
}
return undefined;
}
const SearchNameQueryKey = "name";
function readSearchName(search: string) {
return new URLSearchParams(search).get(SearchNameQueryKey);
}
function FilterBar(): React.JSX.Element {
const history = useHistory();
const location = useLocation();
const [value, setValue] = useState<string | null>(null);
useEffect(() => {
setValue(readSearchName(location.search));
}, [location]);
InputValue = value;
return (
<>
<SearchBox
styles={{
root: {
border: "1px solid #D1D1D1",
height: "52px",
maxWidth: "740px",
borderRadius: "4px",
},
icon: {
fontSize: "24px",
paddingLeft: "10px",
},
field: {
paddingLeft: "20px",
fontSize: "18px",
},
}}
id="filterBar"
value={readSearchName(location.search) != null ? value : ""}
placeholder="Search for an azd template..."
role="search"
onClear={(e) => {
setValue(null);
const newSearch = new URLSearchParams(location.search);
newSearch.delete(SearchNameQueryKey);
history.push({
...location,
search: newSearch.toString(),
state: prepareUserState(),
});
}}
onChange={(e) => {
if (!e) {
return;
}
setValue(e.currentTarget.value);
const newSearch = new URLSearchParams(location.search);
newSearch.delete(SearchNameQueryKey);
if (e.currentTarget.value) {
newSearch.set(SearchNameQueryKey, e.currentTarget.value);
}
history.push({
...location,
search: newSearch.toString(),
state: prepareUserState(),
});
setTimeout(() => {
document.getElementById("searchbar")?.focus();
}, 0);
}}
/>
</>
);
}
export default function ShowcaseTemplateSearch() {
const { colorMode } = useColorMode();
return (
<div className={styles.searchContainer}>
<img
src={
colorMode != "dark"
? useBaseUrl("/img/coverBackground.png")
: useBaseUrl("/img/coverBackgroundDark.png")
}
className={styles.cover}
onError={({ currentTarget }) => {
currentTarget.style.display = "none";
}}
alt=""
/>
<div className={styles.searchArea}>
<div
style={{
display: "flex",
flexDirection: "column",
}}
>
<h1 className={styles.heroBar}>
<Text
size={800}
align="center"
weight="semibold"
style={{
background:
"linear-gradient(90deg, rgb(112.68, 94.63, 239.06) 0%, rgb(41.21, 120.83, 190.19) 100%)",
WebkitBackgroundClip: "text",
WebkitTextFillColor: "transparent",
}}
>
{TITLE}
</Text>
</h1>
<Text
align="center"
size={400}
style={{
color: "#242424",
padding: "10px 0 20px 0",
}}
>
{DESCRIPTION}
</Text>
<FilterBar />
<Text
align="center"
size={300}
style={{
color: "#242424",
paddingTop: "20px",
}}
>
Each template is a fully working, cloud-ready application deployable
with the Azure Developer CLI (azd).{" "}
</Text>
<Text
align="center"
size={300}
style={{
color: "#242424",
paddingBottom: "20px",
}}
>
New to azd? Welcome!
<FluentUILink
href={ADD_URL}
target="_blank"
style={{ paddingLeft: "3px" }}
className={styles.learnMoreColor}
>
Learn more in our docs.
</FluentUILink>
</Text>
</div>
</div>
</div>
);
}