construct-hub 0.2.63 → 0.2.64

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["constants/pageInfo.ts","components/Page/Page.tsx","hooks/useQueryParams/useQueryParams.ts","hooks/useLanguage/useLanguage.ts","constants/keywords.ts","components/LanguageSupportTooltip/LanguageSupportTooltip.tsx","components/PackageTag/PackageTag.tsx","components/Time/Time.tsx","components/PackageCard/constants.ts","util/css.ts","components/PackageCard/testIds.ts","components/PackageCard/Details.tsx","components/PackageCard/Heading.tsx","components/PackageCard/Highlight.tsx","components/PackageLanguages/PackageLanguages.tsx","components/PackageCard/Languages.tsx","components/PackageCard/Tags.tsx","components/PackageCard/WideCard.tsx","components/PackageCard/PackageCard.tsx","views/SearchResults/components/ArrowButton.tsx","views/SearchResults/components/GoToPage.tsx","views/SearchResults/constants.ts","views/SearchRedesign/FilterHeading.tsx","views/SearchRedesign/CheckboxFilter.tsx","views/SearchRedesign/AuthorFilter.tsx","views/SearchRedesign/RadioFilter.tsx","views/SearchRedesign/util.ts","views/SearchRedesign/SearchState.tsx","views/SearchRedesign/CDKFilter.tsx","views/SearchRedesign/LanguageFilter.tsx","views/SearchRedesign/FilterPanel.tsx","components/PackageList/PackageList.tsx","components/PackageList/WideCardList.tsx","views/SearchRedesign/PageControls.tsx","views/SearchRedesign/SearchDetails.tsx","views/SearchRedesign/constants.ts","views/SearchRedesign/SortFilter.tsx","views/SearchRedesign/SortAndFilterDrawer.tsx","views/SearchRedesign/SortedBy.tsx","views/SearchRedesign/SearchResults.tsx","views/SearchRedesign/testIds.ts","views/SearchRedesign/SearchRedesign.tsx"],"names":["pageInfo","home","event","name","faq","packageProfile","search","siteTerms","notFound","page","pageType","Page","children","meta","pageName","trackPageView","usePageView","useEffect","suffix","title","description","formattedTitle","Helmet","process","content","charSet","property","useQueryParams","useLocation","useMemo","URLSearchParams","defaultLang","Language","TypeScript","LOCAL_KEY","isValidLang","lang","TEMP_SUPPORTED_LANGUAGES","has","getInitialLang","langFromParams","storedLang","localStorage","getItem","useLanguage","options","updateUrl","updateSaved","pathname","hash","useHistory","replace","params","get","QUERY_PARAMS","LANGUAGE","useState","language","setLanguage","set","toString","update","useCallback","val","setItem","KEYWORD_IGNORE_LIST","Set","LanguageSupportTooltip","isSupported","langName","LANGUAGE_NAME_MAP","message","hasArrow","label","placement","PackageTag","value","zIndex","tagProps","NavLink","to","getSearchPath","query","_hover","textDecoration","Time","forwardRef","ref","date","formatString","format","boxProps","as","dateTime","toISOString","displayName","PackageCardType","makeGridAreas","rows","map","row","join","testIds","createTestIds","Detail","dataTestid","icon","fontSize","Details","currentLanguage","usePackageCard","author","metadata","version","data","useStats","downloads","packages","npm","authorName","undefined","Download","toLocaleString","published","Date","color","Heading","comment","constructFramework","cdkType","cdkVersion","majorVersion","Link","getPackagePath","align","CDKTYPE_RENDER_MAP","alt","h","mr","src","imgsrc","w","fontWeight","wordBreak","lineHeight","noOfLines","HIGHLIGHT_RENDER_MAP","official","community","highQuality","Highlight","isOfficial","OFFICIAL_SCOPES","some","scope","includes","direction","spacing","sizes","sm","md","lg","PackageLanguages","isRounded","languages","packageName","size","targets","Object","keys","entries","LANGUAGE_RENDER_MAP","sort","left","right","LANGUAGES","indexOf","info","isSupportedByLibrary","isSupportedByConstructHub","Icon","borderRadius","opacity","Languages","pkg","Tags","keywords","variant","filter","v","Boolean","slice","tag","GRID_AREA","gridAreasMd","gridAreasMobile","WideCard","bg","autoColumns","autoRows","border","boxShadow","wideContainer","gap","p","templateAreas","base","gridArea","display","maxH","overflow","alignItems","alignSelf","templateColumns","templateRows","PackageCardContext","createContext","useContext","PackageCard","Wide","Provider","ArrowButton","offset","getPageUrl","props","borderColor","colorScheme","mx","disabled","GoToPage","pageLimit","inputValue","setInputValue","push","onSubmit","e","preventDefault","parseInt","max","min","onChange","target","textAlign","type","ml","LIMIT","FilterHeading","hint","strategy","Question","px","py","shadow","CheckboxFilter","checkedValues","values","onValueChange","getOnChange","isChecked","isTruncated","AuthorFilter","authors","setAuthors","a","RadioFilter","checkedValue","toNum","result","SearchStateContext","useSearchState","state","Error","SearchStateProvider","langQuery","queryParams","OFFSET","decodeURIComponent","SEARCH_QUERY","split","SORT","CDK_TYPE","cdkMajorParam","CDK_MAJOR","cdkMajor","searchAPI","useCatalogSearch","defaultCdkMajor","defaultCdkType","defaultLanguages","defaultQuery","defaultSort","setQuery","limit","CDKFilter","setCdkType","setCdkMajor","useSearchContext","cdkOptions","cdkTypes","constructFrameworks","reduce","opts","pkgCount","CDKTYPE_NAME_MAP","length","majorsOptions","majorVersions","b","cdk","major","majorNum","languageOptions","key","LanguageFilter","setLanguages","l","TOP_OFFSET","FilterPanel","Card","maxW","minW","pos","top","listViews","items","PackageList","memo","cardView","loading","View","PageControls","nextOffset","prevOffset","justify","ChevronLeftIcon","ChevronRightIcon","Em","SearchDetails","count","filtered","first","last","SORT_RENDER_MAP","CatalogSearchSort","NameAsc","NameDesc","PublishDateAsc","PublishDateDesc","DownloadsDesc","DownloadsAsc","SortFilter","setSort","newSort","SortAndFilterDrawer","drawer","useDisclosure","onClick","onOpen","rightIcon","ChevronDown","pb","SortedBy","selected","Button","pl","pr","SearchResults","isFirstRender","useRef","onSearch","useCatalogResults","results","getUrl","q","current","SearchBar","onQueryChange","SearchRedesign"],"mappings":"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","file":"static/js/9.e8c984d8.chunk.js","sourcesContent":["export const pageInfo = {\n home: {\n event: {\n name: \"Home Load\",\n },\n },\n faq: {\n event: {\n name: \"Frequently Asked Questions Load\",\n },\n },\n packageProfile: {\n event: {\n name: \"Package Profile Load\",\n },\n },\n search: {\n event: {\n name: \"Search Load\",\n },\n },\n siteTerms: {\n event: {\n name: \"Site Terms Load\",\n },\n },\n notFound: {\n page: {\n pageType: \"errorPage\",\n },\n event: {\n name: \"404 Page Load\",\n },\n },\n} as const;\n","import { FunctionComponent, useEffect } from \"react\";\nimport { Helmet } from \"react-helmet\";\nimport { pageInfo } from \"../../constants/pageInfo\";\nimport { usePageView } from \"../../contexts/Analytics\";\n\nexport interface PageProps {\n pageName: keyof typeof pageInfo;\n meta: {\n suffix?: boolean;\n title: string;\n description: string;\n };\n}\n\nexport const Page: FunctionComponent<PageProps> = ({\n children,\n meta,\n pageName,\n}) => {\n const trackPageView = usePageView(pageInfo[pageName]);\n\n useEffect(() => {\n trackPageView();\n }, [trackPageView]);\n\n const { suffix = true, title, description } = meta;\n const formattedTitle = suffix ? `${title} - Construct Hub` : title;\n\n return (\n <>\n <Helmet>\n {process.env.NODE_ENV === \"development\" && (\n <meta\n content=\"default-src 'self' 'unsafe-inline' https://*.awsstatic.com https://amazonwebservices.d2.sc.omtrdc.net; connect-src 'self' https://*.shortbread.aws.dev ws://localhost:3000 https://*.awsstatic.com https://amazonwebservices.d2.sc.omtrdc.net; frame-src 'none'; img-src 'self' https://* http://*.omtrdc.net; object-src 'none'; style-src 'self' 'unsafe-inline';\"\n httpEquiv=\"Content-Security-Policy\"\n />\n )}\n\n <meta content=\"width=device-width, initial-scale=1\" name=\"viewport\" />\n <meta charSet=\"utf-8\" />\n\n <title>{formattedTitle}</title>\n <meta content={formattedTitle} property=\"og:title\" />\n <meta content={formattedTitle} name=\"twitter:title\" />\n <meta content=\"summary\" name=\"twitter:card\" />\n\n <meta content={description} name=\"description\" />\n <meta content={description} property=\"og:description\" />\n <meta content={description} name=\"twitter:description\" />\n </Helmet>\n {children}\n </>\n );\n};\n","import { useMemo } from \"react\";\nimport { useLocation } from \"react-router-dom\";\n\nexport const useQueryParams = () => {\n const { search } = useLocation();\n\n return useMemo(() => new URLSearchParams(search), [search]);\n};\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useLocation, useHistory } from \"react-router-dom\";\nimport { Language, TEMP_SUPPORTED_LANGUAGES } from \"../../constants/languages\";\nimport { QUERY_PARAMS } from \"../../constants/url\";\nimport { useQueryParams } from \"../../hooks/useQueryParams\";\n\n// Only supported language atm\nconst defaultLang = Language.TypeScript;\n\nconst LOCAL_KEY = \"preferred-language\";\n\nconst isValidLang = (lang?: string | Language): lang is Language =>\n lang != null && TEMP_SUPPORTED_LANGUAGES.has(lang as Language);\n\nconst getInitialLang = (langFromParams: string | Language): Language => {\n // First, use language from query params in url\n if (isValidLang(langFromParams)) {\n return langFromParams;\n }\n\n // Next check for one stored in localStorage\n try {\n const storedLang = (localStorage.getItem(LOCAL_KEY) ?? \"\") as Language;\n if (isValidLang(storedLang)) return storedLang;\n } catch {\n // Do nothing, we just don't want to crash if localStorage access is blocked.\n }\n\n // Otherwise fallback to a default\n return defaultLang;\n};\n\nexport interface UseLanguageOptions {\n /**\n * Syncs the preferred language to a query param in URL\n */\n updateUrl?: boolean;\n /**\n * Saves the selected language to localStorage on select\n */\n updateSaved?: boolean;\n}\n\nexport const useLanguage = (options: UseLanguageOptions = {}) => {\n const { updateUrl, updateSaved } = options;\n const { pathname, hash } = useLocation();\n const { replace } = useHistory();\n const params = useQueryParams();\n const langFromParams = params.get(QUERY_PARAMS.LANGUAGE) as Language;\n\n // Passed as function to guarantee it runs on hook mount\n const [language, setLanguage] = useState<Language>(() =>\n getInitialLang(langFromParams)\n );\n\n // State subscribes to query param changes\n useEffect(() => {\n if (isValidLang(langFromParams) && langFromParams !== language) {\n setLanguage(langFromParams);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [langFromParams]);\n\n // Syncs language changes to URL if updateUrl = true\n useEffect(() => {\n if (langFromParams !== language && updateUrl) {\n params.set(QUERY_PARAMS.LANGUAGE, language);\n replace({ pathname, hash, search: params.toString() });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [language, updateUrl]);\n\n const update = useCallback(\n (val: Language) => {\n setLanguage(val);\n\n if (updateSaved) {\n try {\n localStorage.setItem(LOCAL_KEY, val);\n } catch {\n // OK to fail silently\n }\n }\n },\n [updateSaved]\n );\n\n return useMemo(() => [language, update] as const, [language, update]);\n};\n","export const KEYWORD_IGNORE_LIST = new Set([\n \"aws-cdk\",\n \"aws\",\n \"awscdk\",\n \"cdk-construct\",\n \"cdk\",\n \"construct\",\n \"constructs\",\n]);\n","import { Tooltip } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport {\n Language,\n LANGUAGE_NAME_MAP,\n TEMP_SUPPORTED_LANGUAGES,\n} from \"../../constants/languages\";\n\nexport interface LanguageSupportTooltipProps {\n language: Language;\n}\n\nexport const LanguageSupportTooltip: FunctionComponent<LanguageSupportTooltipProps> =\n ({ children, language }) => {\n const isSupported = TEMP_SUPPORTED_LANGUAGES.has(language);\n const langName = LANGUAGE_NAME_MAP[language];\n\n const message = isSupported\n ? `Click to view documentation in ${langName}`\n : `Documentation support for ${langName} is coming soon!`;\n\n return (\n <Tooltip hasArrow label={message} placement=\"top-start\">\n <span>{children}</span>\n </Tooltip>\n );\n };\n","import { Tag, TagLabel, TagProps } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { Language } from \"../../constants/languages\";\nimport { getSearchPath } from \"../../util/url\";\nimport { NavLink } from \"../NavLink\";\n\nexport interface PackageTagProps extends TagProps {\n language?: Language;\n value: string;\n label?: string;\n zIndex?: string | number;\n}\n\nexport const PackageTag: FunctionComponent<PackageTagProps> = ({\n children,\n language,\n value,\n label = value,\n zIndex,\n ...tagProps\n}) => {\n return (\n <NavLink\n aria-label={`Tag: ${label}`}\n to={getSearchPath({ query: `${value}`, language })}\n zIndex={zIndex}\n >\n <Tag\n _hover={{\n textDecoration: \"underline\",\n }}\n {...tagProps}\n >\n <TagLabel>{children}</TagLabel>\n </Tag>\n </NavLink>\n );\n};\n","import { Box, BoxProps, forwardRef } from \"@chakra-ui/react\";\nimport { format } from \"date-fns\";\n\nexport interface TimeOptions {\n date: Date;\n format: string;\n}\n\nexport interface TimeProps extends BoxProps, TimeOptions {}\n\nexport const Time = forwardRef<TimeProps, \"time\">(\n ({ date, format: formatString, ...boxProps }, ref) => {\n return (\n <Box as=\"time\" dateTime={date.toISOString()} ref={ref} {...boxProps}>\n {format(date, formatString)}\n </Box>\n );\n }\n);\n\nTime.displayName = \"Time\";\n","export enum PackageCardType {\n Wide = \"wide\",\n}\n","/**\n * @fileoverview CSS Related Utils\n */\n\n/**\n * Translates a series of grid row definitions into a grid area string\n * ```ts\n * const gridAreas = makeGridAreas(\n * [\"header\", \"header\", \"header\"],\n * [\"aside\", \"main\", \"main\"],\n * [\"aside\", \"footer\", \"footer\"]\n * ); // `\"header header header\" \"aside main main\" \"aside footer footer\"`\n * ```\n */\nexport const makeGridAreas = (...rows: string[][]): string => {\n return rows.map((row) => `\"${row.join(\" \")}\"`).join(\" \");\n};\n","import { createTestIds } from \"../../util/createTestIds\";\n\nconst testIds = createTestIds(\"packageCard\", [\n \"author\",\n \"description\",\n \"downloads\",\n \"languages\",\n \"published\",\n \"title\",\n \"version\",\n \"comment\",\n \"wideContainer\",\n] as const);\n\nexport default testIds;\n","import { DownloadIcon } from \"@chakra-ui/icons\";\nimport { Text } from \"@chakra-ui/react\";\nimport { FunctionComponent, ReactChild } from \"react\";\nimport { useStats } from \"../../contexts/Stats\";\nimport { useLanguage } from \"../../hooks/useLanguage\";\nimport { getSearchPath } from \"../../util/url\";\nimport { NavLink } from \"../NavLink\";\nimport { Time } from \"../Time\";\nimport { usePackageCard } from \"./PackageCard\";\nimport testIds from \"./testIds\";\n\ninterface DetailProps {\n \"data-testid\": string;\n icon?: ReactChild;\n label: string;\n value: ReactChild;\n}\n\nconst Detail: FunctionComponent<DetailProps> = ({\n \"data-testid\": dataTestid,\n icon,\n label,\n value,\n}) => (\n <Text data-testid={dataTestid} fontSize=\"xs\">\n {icon}\n {icon ? \" \" : \"\"}\n <strong>{label}</strong> {value}\n </Text>\n);\n\nexport const Details: FunctionComponent = () => {\n const [currentLanguage] = useLanguage();\n\n const {\n author,\n metadata: { date },\n version,\n name,\n } = usePackageCard();\n\n const { data } = useStats();\n const downloads: number | undefined = data?.packages?.[name]?.downloads?.npm;\n\n const authorName = typeof author === \"string\" ? author : author.name;\n\n return (\n <>\n {downloads !== undefined && downloads >= 10 ? (\n <Detail\n data-testid={testIds.downloads}\n icon={<DownloadIcon />}\n label={downloads.toLocaleString()}\n value={\"Downloads\"}\n />\n ) : (\n <Detail data-testid={testIds.version} label=\"Version\" value={version} />\n )}\n <Detail\n data-testid={testIds.published}\n label=\"Published\"\n value={\n <Time date={new Date(date)} fontSize=\"xs\" format=\"MMM dd, yyyy\" />\n }\n />\n <Detail\n data-testid={testIds.author}\n label=\"Author\"\n value={\n <NavLink\n color=\"blue.500\"\n to={getSearchPath({\n query: authorName,\n language: currentLanguage,\n })}\n >\n {authorName}\n </NavLink>\n }\n />\n </>\n );\n};\n","import {\n Flex,\n Image,\n Heading as ChakraHeading,\n LinkOverlay,\n Text,\n Tooltip,\n} from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { CDKTYPE_RENDER_MAP } from \"../../constants/constructs\";\nimport { useLanguage } from \"../../hooks/useLanguage\";\nimport { getPackagePath } from \"../../util/url\";\nimport { usePackageCard } from \"./PackageCard\";\nimport testIds from \"./testIds\";\n\nexport const Heading: FunctionComponent = () => {\n const [currentLanguage] = useLanguage();\n const {\n comment,\n description,\n metadata: { constructFramework },\n name,\n version,\n } = usePackageCard();\n\n const cdkType = constructFramework?.name;\n const cdkVersion = constructFramework?.majorVersion;\n\n return (\n <>\n <LinkOverlay\n as={Link}\n to={getPackagePath({\n name,\n version,\n language: currentLanguage,\n })}\n >\n <Flex align=\"center\">\n {cdkType && (\n <Tooltip\n hasArrow\n label={\n CDKTYPE_RENDER_MAP[cdkType].name +\n (cdkVersion !== undefined ? ` v${cdkVersion}` : \"\")\n }\n placement=\"top\"\n >\n <Image\n alt={`${CDKTYPE_RENDER_MAP[cdkType].name} icon`}\n h={5}\n mr={2}\n src={CDKTYPE_RENDER_MAP[cdkType].imgsrc}\n w={5}\n zIndex={1}\n />\n </Tooltip>\n )}\n <ChakraHeading\n as=\"h3\"\n color=\"blue.800\"\n data-testid={testIds.title}\n fontSize=\"md\"\n fontWeight=\"bold\"\n wordBreak=\"break-all\"\n >\n {name}\n </ChakraHeading>\n </Flex>\n </LinkOverlay>\n <Text\n color=\"blue.800\"\n data-testid={testIds.description}\n fontSize=\"md\"\n lineHeight=\"tall\"\n noOfLines={4}\n >\n {description || \"No description available.\"}\n </Text>\n {comment && (\n <Text\n data-testid={testIds.comment}\n fontSize=\"md\"\n lineHeight=\"tall\"\n noOfLines={4}\n >\n <Text\n as=\"span\"\n color=\"blue.500\"\n fontSize=\"md\"\n fontWeight=\"bold\"\n lineHeight=\"tall\"\n >\n Editor&apos;s note:{\" \"}\n </Text>\n {comment}\n </Text>\n )}\n </>\n );\n};\n","import { Stack, Image, Text } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { OFFICIAL_SCOPES } from \"../../constants/constructs\";\nimport { usePackageCard } from \"./PackageCard\";\n\nconst HIGHLIGHT_RENDER_MAP = {\n official: {\n imgsrc: \"/assets/construct.png\",\n label: \"Official\",\n color: \"#ED3B00\",\n },\n community: {\n imgsrc: \"/assets/community.png\",\n label: \"Community\",\n color: \"#2F50FE\",\n },\n highQuality: {\n imgsrc: \"/assets/medal.png\",\n label: \"High Quality\",\n color: \"#1F02D4\",\n },\n} as const;\n\n// TODO: We will need a similar solution to tags for determining High Quality, and likely Official\nexport const Highlight: FunctionComponent = () => {\n const { name } = usePackageCard();\n\n const isOfficial = OFFICIAL_SCOPES.some((scope) => name.includes(scope));\n const highlightType = isOfficial ? \"official\" : \"community\";\n const { imgsrc, color, label } = HIGHLIGHT_RENDER_MAP[highlightType];\n\n return (\n <Stack align=\"center\" direction=\"row\" spacing={2}>\n <Image alt={`${label} icon`} src={imgsrc} w={4} />\n <Text color={color} fontWeight=\"bold\">\n {label}\n </Text>\n </Stack>\n );\n};\n","import type { FunctionComponent } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport {\n Language,\n LANGUAGES,\n LANGUAGE_RENDER_MAP,\n TEMP_SUPPORTED_LANGUAGES,\n} from \"../../constants/languages\";\nimport { getPackagePath } from \"../../util/url\";\nimport { LanguageSupportTooltip } from \"../LanguageSupportTooltip\";\n\nconst sizes = {\n sm: 5,\n md: 6,\n lg: 8,\n};\n\nexport interface PackageLanguagesProps {\n isRounded?: boolean;\n languages?: Partial<Record<Language, unknown>>;\n name: string;\n size?: \"sm\" | \"md\" | \"lg\";\n version: string;\n}\n\nexport const PackageLanguages: FunctionComponent<PackageLanguagesProps> = ({\n isRounded = false,\n languages,\n name: packageName,\n size = \"md\",\n version,\n}) => {\n const targets = Object.keys(languages ?? {}) as Language[];\n return (\n <>\n {Object.entries(LANGUAGE_RENDER_MAP)\n // Ensure entries are always sorted in a stable way\n .sort(\n ([left], [right]) =>\n LANGUAGES.indexOf(left as Language) -\n LANGUAGES.indexOf(right as Language)\n )\n .map(([lang, info]) => {\n const language = lang as Language;\n\n const isSupportedByLibrary =\n language === Language.TypeScript || targets.includes(language);\n\n const isSupportedByConstructHub =\n language === Language.TypeScript || // TypeScript is always supported\n // Otherwise, the language must be supported by ConstructHub\n TEMP_SUPPORTED_LANGUAGES.has(language);\n\n if (!isSupportedByLibrary) return null;\n\n const { name, icon: Icon } = info;\n\n const icon = (\n <Icon\n aria-label={`Supports ${name}`}\n borderRadius={isRounded ? \"50%\" : 0}\n h={sizes[size]}\n opacity={isSupportedByConstructHub ? 1 : 0.2}\n w={sizes[size]}\n />\n );\n\n return (\n <LanguageSupportTooltip key={language} language={language}>\n {isSupportedByConstructHub ? (\n <Link\n aria-label={`View package docs for ${language}`}\n to={getPackagePath({ name: packageName, version, language })}\n >\n {icon}\n </Link>\n ) : (\n icon\n )}\n </LanguageSupportTooltip>\n );\n })}\n </>\n );\n};\n","import type { FunctionComponent } from \"react\";\nimport { PackageLanguages } from \"../PackageLanguages\";\nimport { usePackageCard } from \"./PackageCard\";\n\nexport const Languages: FunctionComponent = () => {\n const pkg = usePackageCard();\n return <PackageLanguages {...pkg} size=\"sm\" />;\n};\n","import { FunctionComponent } from \"react\";\nimport { OFFICIAL_SCOPES } from \"../../constants/constructs\";\nimport { KEYWORD_IGNORE_LIST } from \"../../constants/keywords\";\nimport { PackageTag } from \"../PackageTag\";\nimport { usePackageCard } from \"./PackageCard\";\n\n// TODO: Proper tag implemenation, this is only a visual placeholder\nexport const Tags: FunctionComponent = () => {\n const { keywords, name } = usePackageCard();\n\n return (\n <>\n {[\n OFFICIAL_SCOPES.some((scope) => name.includes(scope)) ? (\n <PackageTag\n key=\"official\"\n label=\"official\"\n mr={1}\n value=\"@aws-cdk\"\n variant=\"official\"\n >\n Official\n </PackageTag>\n ) : null,\n ...(keywords ?? [])\n .filter((v) => Boolean(v) && !KEYWORD_IGNORE_LIST.has(v))\n .slice(0, 3)\n .map((tag) => {\n return (\n <PackageTag\n key={tag}\n mr={1}\n value={`\"${tag}\"`}\n zIndex=\"0 !important\"\n >\n {tag}\n </PackageTag>\n );\n }),\n ]}\n </>\n );\n};\n","import { Grid, Stack, LinkBox, Divider } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { makeGridAreas } from \"../../util/css\";\nimport { Details } from \"./Details\";\nimport { Heading } from \"./Heading\";\nimport { Highlight } from \"./Highlight\";\nimport { Languages } from \"./Languages\";\nimport { Tags } from \"./Tags\";\nimport testIds from \"./testIds\";\n\nconst GRID_AREA = {\n DETAILS: \"details\",\n LANGUAGES: \"languages\",\n TAGS: \"tags\",\n HEADING: \"heading\",\n};\n\nconst gridAreasMd = makeGridAreas(\n [GRID_AREA.HEADING, GRID_AREA.HEADING, GRID_AREA.DETAILS],\n [GRID_AREA.HEADING, GRID_AREA.HEADING, GRID_AREA.DETAILS],\n [GRID_AREA.TAGS, GRID_AREA.TAGS, GRID_AREA.LANGUAGES]\n);\n\nconst gridAreasMobile = makeGridAreas(\n [GRID_AREA.HEADING],\n [GRID_AREA.LANGUAGES],\n [GRID_AREA.DETAILS]\n);\n\nexport const WideCard: FunctionComponent = () => {\n return (\n <LinkBox\n _hover={{\n \"> article\": {\n bg: \"gray.50\",\n },\n }}\n >\n <Grid\n as=\"article\"\n autoColumns=\"1fr\"\n autoRows=\"auto\"\n bg=\"white\"\n border=\"base\"\n borderRadius=\"sm\"\n boxShadow=\"base\"\n color=\"gray.600\"\n data-testid={testIds.wideContainer}\n gap={5}\n h=\"100%\"\n p={5}\n templateAreas={{ base: gridAreasMobile, md: gridAreasMd }}\n w=\"100%\"\n >\n {/* Name + Desc */}\n <Stack gridArea={GRID_AREA.HEADING} spacing={2}>\n <Heading />\n </Stack>\n\n <Stack\n direction=\"row\"\n display={{ base: \"none\", md: \"initial\" }}\n gridArea={GRID_AREA.TAGS}\n maxH={6}\n overflow=\"hidden\"\n >\n <Tags />\n </Stack>\n\n <Grid\n alignItems=\"start\"\n alignSelf=\"center\"\n autoColumns={{ base: \"initial\", md: \"1fr\" }}\n autoRows={{ base: \"initial\", md: \"auto\" }}\n fontSize=\"xs\"\n gap={{ base: 0, md: 1 }}\n gridArea={GRID_AREA.DETAILS}\n templateColumns={{ base: \"1fr 1fr\", md: \"initial\" }}\n templateRows={{ base: \"1fr 1fr\", md: \"initial\" }}\n >\n <Highlight />\n <Details />\n </Grid>\n\n <Stack gridArea={GRID_AREA.LANGUAGES} spacing={{ base: 4, md: 0 }}>\n <Divider display={{ md: \"none\" }} />\n <Stack data-testid={testIds.languages} direction=\"row\" spacing={2}>\n <Languages />\n </Stack>\n </Stack>\n </Grid>\n </LinkBox>\n );\n};\n","import { createContext, FunctionComponent, useContext } from \"react\";\nimport { CatalogPackage } from \"../../api/package/packages\";\nimport { PackageCardType } from \"./constants\";\nimport { WideCard } from \"./WideCard\";\n\nexport interface PackageCardProps {\n pkg: CatalogPackage;\n variant?: PackageCardType;\n}\n\nconst PackageCardContext = createContext<\n (CatalogPackage & { comment?: string }) | null\n>(null);\n\nexport const usePackageCard = () => useContext(PackageCardContext)!;\n\nexport const PackageCard: FunctionComponent<PackageCardProps> = ({\n pkg,\n variant = PackageCardType.Wide,\n}) => {\n return (\n <PackageCardContext.Provider value={pkg}>\n {variant === PackageCardType.Wide && <WideCard />}\n </PackageCardContext.Provider>\n );\n};\n","import { IconButton, IconProps } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { Link } from \"react-router-dom\";\n\nexport interface ArrowButtonProps {\n icon: FunctionComponent<IconProps>;\n offset?: number;\n getPageUrl: (params: { offset: number }) => string;\n}\n\nexport const ArrowButton: FunctionComponent<ArrowButtonProps> = ({\n icon: Icon,\n offset,\n getPageUrl,\n}) => {\n const label = `Page ${offset} link`;\n\n const props = {\n \"aria-label\": label,\n borderRadius: \"md\",\n borderColor: \"blue.500\",\n colorScheme: \"blue\",\n icon: <Icon color=\"blue.500\" h={5} w={5} />,\n mx: 2,\n h: 10,\n w: 10,\n variant: \"outline\",\n };\n\n if (offset !== undefined) {\n return <IconButton {...props} as={Link} to={getPageUrl({ offset })} />;\n }\n\n return <IconButton {...props} disabled />;\n};\n","import { Flex, Input, Text } from \"@chakra-ui/react\";\nimport {\n FormEventHandler,\n FunctionComponent,\n SyntheticEvent,\n useEffect,\n useState,\n} from \"react\";\nimport { useHistory } from \"react-router-dom\";\n\nexport interface GoToPageProps {\n pageLimit: number;\n offset: number;\n getPageUrl: (params: { offset: number }) => string;\n}\n\nexport const GoToPage: FunctionComponent<GoToPageProps> = ({\n pageLimit,\n offset,\n getPageUrl,\n}) => {\n const [inputValue, setInputValue] = useState((offset + 1).toString());\n const { push } = useHistory();\n\n useEffect(() => {\n setInputValue((offset + 1).toString());\n }, [offset]);\n\n const onInputChange = (e: SyntheticEvent<HTMLInputElement>) => {\n e.preventDefault();\n setInputValue((e.target as HTMLInputElement).value);\n };\n\n const onSubmit: FormEventHandler<HTMLInputElement> = (e) => {\n e.preventDefault();\n push(getPageUrl({ offset: parseInt(inputValue) - 1 }));\n };\n\n return (\n <Flex align=\"center\" as=\"form\" mx={2} onSubmit={onSubmit}>\n <Input\n colorScheme=\"blue\"\n h={10}\n max={pageLimit + 1}\n min={1}\n name=\"page\"\n onChange={onInputChange}\n p={0}\n textAlign=\"center\"\n type=\"number\"\n value={inputValue}\n w={10}\n />\n <Text ml={2} w=\"max-content\">\n of {pageLimit + 1}\n </Text>\n </Flex>\n );\n};\n","import type { QueryParamKey } from \"../../constants/url\";\n\nexport const LIMITS = [25, 50, 75, 100];\nexport const LIMIT = LIMITS[0];\n\nexport type SearchQueryParam = Extract<QueryParamKey, \"offset\" | \"q\">;\n","import { QuestionIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Heading,\n Text,\n Popover,\n IconButton,\n PopoverHeader,\n PopoverTrigger,\n PopoverBody,\n PopoverCloseButton,\n PopoverArrow,\n PopoverContent,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\n\nexport interface FilterHeadingProps {\n name: string;\n hint?: string;\n}\n\nexport const FilterHeading: FunctionComponent<FilterHeadingProps> = ({\n name,\n hint,\n}) => {\n return (\n <Flex align=\"center\">\n <Heading as=\"h4\" size=\"sm\" w=\"max-content\">\n {name}\n </Heading>\n {hint ? (\n <Popover colorScheme=\"dark\" placement=\"top-end\" strategy=\"fixed\">\n <PopoverTrigger>\n <IconButton\n aria-label={`Hint: ${name}`}\n icon={<QuestionIcon h={4} w={4} />}\n ml={2}\n px={0}\n py={0}\n size=\"sm\"\n variant=\"ghost\"\n />\n </PopoverTrigger>\n <PopoverContent\n bg=\"gray.700\"\n color=\"white\"\n fontSize=\"sm\"\n shadow=\"whiteAlpha.300\"\n >\n <PopoverHeader>Hint: {name}</PopoverHeader>\n <PopoverCloseButton />\n <PopoverArrow />\n <PopoverBody>\n <Text>{hint}</Text>\n </PopoverBody>\n </PopoverContent>\n </Popover>\n ) : null}\n </Flex>\n );\n};\n","import { Checkbox, Stack, Text } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { FilterHeading, FilterHeadingProps } from \"./FilterHeading\";\n\nexport interface CheckboxFilterProps extends FilterHeadingProps {\n options: {\n display: string;\n value: string;\n }[];\n values: string[];\n onValueChange: (value: string) => void;\n}\n\nexport const CheckboxFilter: FunctionComponent<CheckboxFilterProps> = ({\n hint,\n name,\n options,\n values: checkedValues,\n onValueChange,\n}) => {\n const getOnChange = (value: string) => () => {\n onValueChange(value);\n };\n\n return (\n <Stack spacing={2}>\n <FilterHeading hint={hint} name={name} />\n {options.map(({ display, value }) => (\n <Checkbox\n isChecked={checkedValues.includes(value)}\n key={value}\n onChange={getOnChange(value)}\n >\n <Text color=\"gray.600\" fontSize=\"sm\" isTruncated>\n {display}\n </Text>\n </Checkbox>\n ))}\n </Stack>\n );\n};\n","import { FunctionComponent, useState } from \"react\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\n\n// TODO: This filter is currently non-functional\nexport const AuthorFilter: FunctionComponent = () => {\n const [authors, setAuthors] = useState<string[]>([]);\n\n const onAuthorsChange = (author: string) => {\n setAuthors(\n authors.includes(author)\n ? authors.filter((a) => a !== author)\n : [...authors, author]\n );\n };\n\n return (\n <CheckboxFilter\n name=\"Author\"\n onValueChange={onAuthorsChange}\n options={[\n {\n display: \"Community\",\n value: \"community\",\n },\n {\n display: \"AWS\",\n value: \"aws\",\n },\n ]}\n values={authors}\n />\n );\n};\n","import { Radio, RadioGroup, Stack, Text } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { FilterHeading, FilterHeadingProps } from \"./FilterHeading\";\n\nexport interface RadioFilterProps extends FilterHeadingProps {\n value?: string;\n onValueChange: (value: string) => void;\n options: {\n display: string;\n value: string;\n }[];\n}\n\nexport const RadioFilter: FunctionComponent<RadioFilterProps> = ({\n value: checkedValue,\n onValueChange,\n options,\n name,\n hint,\n}) => {\n return (\n <Stack spacing={2}>\n <FilterHeading hint={hint} name={name} />\n <RadioGroup onChange={onValueChange} value={checkedValue}>\n <Stack>\n {options.map(({ display, value }) => (\n <Radio key={value} value={value}>\n <Text color=\"gray.600\" fontSize=\"sm\" isTruncated>\n {display}\n </Text>\n </Radio>\n ))}\n </Stack>\n </RadioGroup>\n </Stack>\n );\n};\n","import { Language } from \"../../constants/languages\";\n\nexport const toNum = (val: string) => {\n const result = parseInt(val);\n\n if (`${result}` === \"NaN\") {\n return 0;\n }\n\n return result;\n};\n\nexport const parseLangs = (langQuery: string | null) => {\n if (!langQuery) return [];\n\n const langs = decodeURIComponent(langQuery).split(\",\");\n return langs as Language[];\n};\n","/**\n * @fileoverview Exposes page-level state and setters to all components in the new SearchResults View.\n */\nimport { createContext, FunctionComponent, useContext, useEffect } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { CDKType } from \"../../constants/constructs\";\nimport { QUERY_PARAMS } from \"../../constants/url\";\nimport {\n UseCatalogSearchReturn,\n useCatalogSearch,\n} from \"../../hooks/useCatalogSearch\";\nimport { useQueryParams } from \"../../hooks/useQueryParams\";\nimport { LIMIT } from \"../SearchResults/constants\";\nimport { parseLangs, toNum } from \"./util\";\n\nexport interface SearchState {\n limit: number;\n offset: number;\n query: string;\n searchAPI: UseCatalogSearchReturn;\n}\n\nconst SearchStateContext = createContext<SearchState | undefined>(undefined);\n\n/**\n * A hook to access Search Page specific state. This can only be in descendants of the new Search Page\n * and will otherwise throw an error.\n */\nexport const useSearchState = () => {\n const state = useContext(SearchStateContext);\n\n if (!state) {\n throw new Error(\n `This hook must be called in a child of <SearchStateProvider />`\n );\n }\n\n return state;\n};\n\nexport const SearchStateProvider: FunctionComponent = ({ children }) => {\n const queryParams = useQueryParams();\n\n const offset = toNum(queryParams.get(QUERY_PARAMS.OFFSET) ?? \"0\");\n\n const query = decodeURIComponent(\n queryParams.get(QUERY_PARAMS.SEARCH_QUERY) ?? \"\"\n );\n\n const languages = parseLangs(queryParams.get(QUERY_PARAMS.LANGUAGES));\n\n const sort = (queryParams.get(QUERY_PARAMS.SORT) ?? undefined) as\n | CatalogSearchSort\n | undefined;\n\n const cdkType =\n (queryParams.get(QUERY_PARAMS.CDK_TYPE) as CDKType) ?? undefined;\n\n const cdkMajorParam = queryParams.get(QUERY_PARAMS.CDK_MAJOR);\n const cdkMajor = cdkMajorParam ? toNum(cdkMajorParam) : undefined;\n\n const searchAPI = useCatalogSearch({\n defaultCdkMajor: cdkMajor,\n defaultCdkType: cdkType,\n defaultLanguages: languages,\n defaultQuery: query,\n defaultSort: sort,\n });\n\n useEffect(() => {\n if (query !== searchAPI.query) {\n searchAPI.setQuery(query);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [query]);\n\n return (\n <SearchStateContext.Provider\n value={{\n limit: LIMIT,\n offset,\n query,\n searchAPI,\n }}\n >\n {children}\n </SearchStateContext.Provider>\n );\n};\n","import { FunctionComponent, useMemo } from \"react\";\nimport { CatalogConstructFrameworkMeta } from \"../../api/catalog-search\";\nimport { CDKType, CDKTYPE_NAME_MAP } from \"../../constants/constructs\";\nimport { useSearchContext } from \"../../contexts/Search\";\nimport { RadioFilter } from \"./RadioFilter\";\nimport { useSearchState } from \"./SearchState\";\n\ntype CDKOptions = Partial<{\n [key in CDKType]: CatalogConstructFrameworkMeta & {\n display: string;\n value: key;\n };\n}>;\n\nexport const CDKFilter: FunctionComponent = () => {\n const { cdkType, setCdkType, cdkMajor, setCdkMajor } =\n useSearchState().searchAPI;\n const searchAPI = useSearchContext()!;\n\n // Options with less than one package will be omitted\n const cdkOptions = useMemo(() => {\n const cdkTypes = searchAPI.constructFrameworks;\n const options = Object.entries(cdkTypes).reduce((opts, [name, meta]) => {\n if (meta.pkgCount < 1) {\n return opts;\n }\n\n return {\n ...opts,\n [name]: {\n display: CDKTYPE_NAME_MAP[name as CDKType],\n value: name,\n ...meta,\n },\n };\n }, {});\n\n return Object.keys(options).length ? (options as CDKOptions) : undefined;\n }, [searchAPI]);\n\n const majorsOptions = useMemo(() => {\n if (!cdkOptions || !cdkType) return undefined;\n const majorVersions = cdkOptions[cdkType]?.majorVersions;\n\n if (!majorVersions) return undefined;\n\n return [...majorVersions]\n .sort((a, b) => a - b)\n .map((value) => ({\n value: value.toString(),\n display: `${CDKTYPE_NAME_MAP[cdkType]} v${value}`,\n }));\n }, [cdkOptions, cdkType]);\n\n if (!cdkOptions) {\n return null;\n }\n\n const onCdkTypeChange = (type: string) => {\n const cdk = type as CDKType;\n setCdkMajor(undefined);\n setCdkType(type ? cdk : undefined);\n };\n\n const onCdkMajorChange = (major: string) => {\n if (!major) {\n setCdkMajor(undefined);\n return;\n }\n\n const majorNum = parseInt(major, 10);\n\n setCdkMajor(majorNum);\n };\n\n return (\n <>\n <RadioFilter\n hint=\"Constructs support distinct output types: AWS CDK libraries output Cloudformation Templates, CDK8s libraries output Kubernetes manifests, and CDKtf libraries output Terraform Configuration. The Construct Hub attempts to detect the output type of each library, but results are not guaranteed to be completely accurate.\"\n name=\"CDK Type\"\n onValueChange={onCdkTypeChange}\n options={[\n { display: \"Any CDK Type\", value: \"\" },\n ...Object.values(cdkOptions),\n ]}\n value={cdkType ?? \"\"}\n />\n {/* No point in showing major versions if only a single one is available */}\n {!!(majorsOptions && majorsOptions.length > 1) && (\n <RadioFilter\n hint={`Allows you to filter by a major version of your selected CDK Type: (${\n CDKTYPE_NAME_MAP[cdkType!]\n })`}\n name=\"CDK Major Version\"\n onValueChange={onCdkMajorChange}\n options={[\n { display: \"Any Major Version\", value: \"\" },\n ...majorsOptions,\n ]}\n value={cdkMajor?.toString() ?? \"\"}\n />\n )}\n </>\n );\n};\n","import { FunctionComponent } from \"react\";\nimport {\n Language,\n LANGUAGE_NAME_MAP,\n TEMP_SUPPORTED_LANGUAGES,\n} from \"../../constants/languages\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\nimport { useSearchState } from \"./SearchState\";\n\nconst languageOptions = Object.entries(LANGUAGE_NAME_MAP)\n .filter(([key]) => TEMP_SUPPORTED_LANGUAGES.has(key as Language))\n .map(([key, value]) => ({\n display: value,\n value: key,\n }));\n\nexport const LanguageFilter: FunctionComponent = () => {\n const { languages, setLanguages } = useSearchState().searchAPI;\n\n const onLanguagesChange = (lang: string) => {\n const language = lang as Language;\n\n setLanguages(\n languages.includes(language)\n ? languages.filter((l) => l !== language)\n : [...languages, language]\n );\n };\n\n return (\n <CheckboxFilter\n hint=\"Select one or more programming languages to filter by. Results will match at least one of the selected languages. If no languages are selected, results will not be filtered by langauges.\"\n name=\"Programming Language\"\n onValueChange={onLanguagesChange}\n options={languageOptions}\n values={languages}\n />\n );\n};\n","import { Heading, Stack } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { Card } from \"../../components/Card\";\nimport { AuthorFilter } from \"./AuthorFilter\";\nimport { CDKFilter } from \"./CDKFilter\";\nimport { LanguageFilter } from \"./LanguageFilter\";\n\nexport interface FilterPanelProps {}\n\n// Header height + section padding\nconst TOP_OFFSET = \"5.75rem\";\n\n/**\n * The desktop Resolution Filter Panel\n */\nexport const FilterPanel: FunctionComponent<FilterPanelProps> = () => {\n return (\n <Card\n borderRadius=\"none\"\n boxShadow=\"none\"\n display={{ base: \"none\", md: \"flex\" }}\n maxH={`calc(100vh - ${TOP_OFFSET} - 1.25rem)`}\n maxW=\"23rem\"\n minW=\"100%\"\n overflow=\"hidden auto\"\n p={4}\n pos=\"sticky\"\n top={TOP_OFFSET}\n zIndex=\"docked\"\n >\n <Stack color=\"blue.800\" h=\"max-content\" spacing={6} top={4}>\n <Heading as=\"h3\" size=\"sm\">\n Filters\n </Heading>\n <CDKFilter />\n <LanguageFilter />\n <AuthorFilter />\n </Stack>\n </Card>\n );\n};\n","import { Center, Spinner } from \"@chakra-ui/react\";\nimport { FunctionComponent, memo } from \"react\";\nimport { CatalogPackage } from \"../../api/package/packages\";\nimport { PackageCardType } from \"../PackageCard\";\nimport { WideCardList } from \"./WideCardList\";\n\nconst listViews = {\n [PackageCardType.Wide]: WideCardList,\n};\n\nexport interface PackageListViewProps {\n items: CatalogPackage[];\n}\n\nexport interface PackageListProps extends Partial<PackageListViewProps> {\n cardView?: PackageCardType;\n loading?: boolean;\n title?: string;\n}\n\nexport const PackageList: FunctionComponent<PackageListProps> = memo(\n ({\n cardView = PackageCardType.Wide,\n items,\n loading,\n // title,\n }) => {\n if (loading || !items) {\n return (\n <Center>\n <Spinner size=\"xl\" />\n </Center>\n );\n }\n\n const View = listViews[cardView];\n\n return <View items={items} />;\n }\n);\n\nPackageList.displayName = \"PackageList\";\n","import { Stack } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { PackageCard, PackageCardType } from \"../PackageCard\";\nimport { PackageListViewProps } from \"./PackageList\";\n\nexport const WideCardList: FunctionComponent<PackageListViewProps> = ({\n items,\n}) => {\n return (\n <Stack spacing={4}>\n {items.map((pkg) => (\n <PackageCard\n key={`${pkg.name}-${pkg.version}`}\n pkg={pkg}\n variant={PackageCardType.Wide}\n />\n ))}\n </Stack>\n );\n};\n","import { ChevronLeftIcon, ChevronRightIcon } from \"@chakra-ui/icons\";\nimport { Stack } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { ArrowButton } from \"../SearchResults/components/ArrowButton\";\nimport { GoToPage } from \"../SearchResults/components/GoToPage\";\n\nexport interface PageControlsProps {\n offset: number;\n pageLimit: number;\n getPageUrl: (params: { offset?: number }) => string;\n}\n\nexport const PageControls: FunctionComponent<PageControlsProps> = ({\n offset,\n getPageUrl,\n pageLimit,\n}) => {\n const nextOffset = offset < pageLimit ? offset + 1 : undefined;\n const prevOffset = offset > 0 ? offset - 1 : undefined;\n\n return (\n <Stack\n align=\"center\"\n direction=\"row\"\n justify=\"space-between\"\n maxW=\"18rem\"\n mx=\"auto\"\n spacing={4}\n w=\"full\"\n >\n <ArrowButton\n getPageUrl={getPageUrl}\n icon={ChevronLeftIcon}\n offset={prevOffset}\n />\n <GoToPage getPageUrl={getPageUrl} offset={offset} pageLimit={pageLimit} />\n <ArrowButton\n getPageUrl={getPageUrl}\n icon={ChevronRightIcon}\n offset={nextOffset}\n />\n </Stack>\n );\n};\n","import { Text } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\n\nexport interface SearchDetailsProps {\n limit: number;\n offset: number;\n count: number;\n filtered: boolean;\n query?: string;\n}\n\nconst Em: FunctionComponent = ({ children }) => (\n <Text as=\"strong\" color=\"gray.700\">\n {children}\n </Text>\n);\n\nexport const SearchDetails: FunctionComponent<SearchDetailsProps> = ({\n limit,\n offset,\n count,\n filtered,\n query,\n}) => {\n const first = limit * offset;\n const last = first + limit;\n return (\n <Text>\n Displaying{\" \"}\n <Em>\n {count ? first + 1 : count} - {last > count ? count : last}\n </Em>{\" \"}\n of <Em>{count}</Em> {filtered ? \"search results\" : \"constructs\"}\n {query && (\n <>\n {\" for \"}\n <Em>{query}</Em>\n </>\n )}\n </Text>\n );\n};\n","import { CatalogSearchSort } from \"../../api/catalog-search/constants\";\n\nexport const SORT_RENDER_MAP = {\n [CatalogSearchSort.NameAsc]: \"A-Z\",\n [CatalogSearchSort.NameDesc]: \"Z-A\",\n [CatalogSearchSort.PublishDateAsc]: \"Oldest first\",\n [CatalogSearchSort.PublishDateDesc]: \"Newest first\",\n [CatalogSearchSort.DownloadsDesc]: \"Most downloads\",\n [CatalogSearchSort.DownloadsAsc]: \"Least downloads\",\n};\n","import { FunctionComponent } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { SORT_RENDER_MAP } from \"./constants\";\nimport { RadioFilter } from \"./RadioFilter\";\nimport { useSearchState } from \"./SearchState\";\n\nexport const SortFilter: FunctionComponent = () => {\n const { sort, setSort } = useSearchState().searchAPI;\n\n const onSortChange = (newSort: string) => {\n setSort(newSort ? (newSort as CatalogSearchSort) : undefined);\n };\n\n return (\n <RadioFilter\n hint=\"Sets the order of search results\"\n name=\"Sorted By\"\n onValueChange={onSortChange}\n options={[\n { display: \"Relevance\", value: \"\" },\n ...Object.entries(SORT_RENDER_MAP).map(([value, display]) => ({\n display,\n value,\n })),\n ]}\n value={sort ?? \"\"}\n />\n );\n};\n","import { ChevronDownIcon } from \"@chakra-ui/icons\";\nimport {\n Button,\n Drawer,\n Stack,\n DrawerBody,\n DrawerHeader,\n DrawerOverlay,\n DrawerContent,\n DrawerCloseButton,\n useDisclosure,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { AuthorFilter } from \"./AuthorFilter\";\nimport { CDKFilter } from \"./CDKFilter\";\nimport { LanguageFilter } from \"./LanguageFilter\";\nimport { SortFilter } from \"./SortFilter\";\n\n/**\n * The mobile filter Drawer (Bottomsheet in iOS terminology)\n */\nexport const SortAndFilterDrawer: FunctionComponent = () => {\n const drawer = useDisclosure();\n\n return (\n <>\n <Button\n colorScheme=\"blue\"\n display={{ md: \"none\" }}\n onClick={drawer.onOpen}\n rightIcon={<ChevronDownIcon />}\n variant=\"link\"\n >\n Sorting and Filters\n </Button>\n <Drawer {...drawer} placement=\"bottom\">\n <DrawerOverlay />\n\n <DrawerContent color=\"blue.800\">\n <DrawerHeader>Sorting and Filters</DrawerHeader>\n\n <DrawerCloseButton />\n\n <DrawerBody>\n <Stack color=\"blue.800\" pb={4} spacing={4}>\n <SortFilter />\n\n <CDKFilter />\n\n <LanguageFilter />\n\n <AuthorFilter />\n </Stack>\n </DrawerBody>\n </DrawerContent>\n </Drawer>\n </>\n );\n};\n","import { ChevronDownIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Text,\n Menu,\n MenuButton,\n MenuList,\n MenuItem,\n Button,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { SORT_RENDER_MAP } from \"./constants\";\nimport { useSearchState } from \"./SearchState\";\n\nexport const SortedBy: FunctionComponent = () => {\n const { searchAPI } = useSearchState();\n const { sort, setSort } = searchAPI;\n\n const selected = sort ? SORT_RENDER_MAP[sort] : \"Relevance\";\n\n return (\n <Flex align=\"center\">\n <Text>Sorted by</Text>\n <Menu>\n <MenuButton\n as={Button}\n color=\"blue.500\"\n ml={2}\n pl={2} // For some reason, the px shorthand doesn't work on this Button\n pr={2}\n py={1}\n rightIcon={<ChevronDownIcon />}\n variant=\"link\"\n >\n {selected}\n </MenuButton>\n <MenuList minW=\"180\" zIndex=\"sticky\">\n <MenuItem key=\"Relevance\" onClick={() => setSort(undefined)}>\n Relevance\n </MenuItem>\n {Object.entries(SORT_RENDER_MAP).map(([value, display]) => (\n <MenuItem\n key={value}\n onClick={() => setSort(value as CatalogSearchSort)}\n >\n {display}\n </MenuItem>\n ))}\n </MenuList>\n </Menu>\n </Flex>\n );\n};\n","import { Box, Stack } from \"@chakra-ui/react\";\nimport { FunctionComponent, useEffect, useRef } from \"react\";\nimport { useHistory } from \"react-router-dom\";\nimport { PackageList } from \"../../components/PackageList\";\nimport { Page } from \"../../components/Page\";\nimport { SearchBar } from \"../../components/SearchBar\";\nimport { useCatalogResults } from \"../../hooks/useCatalogResults\";\nimport { getSearchPath } from \"../../util/url\";\nimport { SearchQueryParam } from \"../SearchResults/constants\";\nimport { PageControls } from \"./PageControls\";\nimport { SearchDetails } from \"./SearchDetails\";\nimport { useSearchState } from \"./SearchState\";\nimport { SortAndFilterDrawer } from \"./SortAndFilterDrawer\";\nimport { SortedBy } from \"./SortedBy\";\n\nexport const SearchResults: FunctionComponent = () => {\n const isFirstRender = useRef(true);\n const { push } = useHistory();\n\n const { query, searchAPI, offset, limit } = useSearchState();\n const { languages, sort, cdkType, cdkMajor, onSearch } = searchAPI;\n\n const { page, pageLimit, results } = useCatalogResults({\n offset,\n limit,\n query,\n languages,\n cdkMajor,\n cdkType,\n sort,\n });\n\n const getUrl = (\n params: Partial<{ [key in SearchQueryParam]: number | string }>\n ) => {\n return getSearchPath({\n cdkMajor,\n cdkType,\n query: (params.q ?? query) as string,\n languages,\n sort,\n offset: params.offset ?? offset,\n });\n };\n\n // Resets the page number to 1 if query param offset is below 0, or to the last page if offset is higher than page count\n useEffect(() => {\n // If the query has results but the page has nothing to show...\n if (results.length && (offset < 0 || offset > pageLimit)) {\n // Handle an out of bounds offset\n if (offset < 0) {\n push(getUrl({ offset: 0 }));\n } else {\n // Offset is too large, just take last page\n push(getUrl({ offset: pageLimit }));\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [results, offset, pageLimit]);\n\n // Reset offset and update url when query, filters, or sort change\n // We want to avoid doing this on first render / when a user directly navigates to a search URL\n // so we keep a ref to prevent this\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n } else {\n // Trigger a history replace rather than push to avoid bloating browser history\n onSearch({ replace: true });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [sort, languages, cdkType, cdkMajor]);\n\n return (\n <Page\n meta={{\n title: query || \"Search\",\n description: query\n ? `${results.length} results for ${query} at Construct Hub`\n : \"Search reusable components for your cloud application\",\n }}\n pageName=\"search\"\n >\n <Stack direction=\"column\" maxW=\"100vw\" pb={4} px={4} spacing={4}>\n <SearchBar\n bg=\"white\"\n onChange={searchAPI.onQueryChange}\n onSubmit={searchAPI.onSubmit}\n value={searchAPI.query}\n />\n\n <Stack\n align={{ base: \"start\", lg: \"center\" }}\n direction={{ base: \"column-reverse\", lg: \"row\" }}\n justify={{ base: \"initial\", lg: \"space-between\" }}\n spacing={4}\n >\n <SearchDetails\n count={results.length}\n filtered={!!query}\n limit={limit}\n offset={offset}\n query={query}\n />\n\n <Box display={{ base: \"none\", md: \"initial\" }}>\n <SortedBy />\n </Box>\n\n <Box display={{ md: \"none\" }}>\n <SortAndFilterDrawer />\n </Box>\n </Stack>\n\n <PackageList items={page} />\n\n <Box w=\"full\">\n <PageControls\n getPageUrl={getUrl}\n offset={offset}\n pageLimit={pageLimit}\n />\n </Box>\n </Stack>\n </Page>\n );\n};\n","import { createTestIds } from \"../../util/createTestIds\";\n\nexport default createTestIds(\"searchRedesign\", [\"page\"] as const);\n","import { Grid } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { Page } from \"../../components/Page\";\nimport { FilterPanel } from \"./FilterPanel\";\nimport { SearchResults } from \"./SearchResults\";\nimport { SearchStateProvider } from \"./SearchState\";\nimport testIds from \"./testIds\";\n\nexport const SearchRedesign: FunctionComponent = () => {\n return (\n <SearchStateProvider>\n <Page\n meta={{\n title: \"Search - Construct Hub\",\n description:\n \"Search Construct Libraries for AWS CDK, CDK8s, and CDKtf\",\n }}\n pageName=\"search\"\n >\n <Grid\n data-testid={testIds.page}\n gap={4}\n h=\"full\"\n maxW=\"100%\"\n px={{ base: 0, md: 6 }}\n py={6}\n templateColumns={{ base: \"1fr\", md: \"auto 1fr\" }}\n templateRows=\"1fr\"\n >\n {/* Filter Panel Desktop */}\n <FilterPanel />\n\n {/* Results, Info, and Controls */}\n <SearchResults />\n </Grid>\n </Page>\n </SearchStateProvider>\n );\n};\n"],"sourceRoot":""}