{ "version": 3, "sources": ["../javascripts/hooks/useSuggestion.ts", "../javascripts/styled-components/components/SuggestionList/index.tsx", "../javascripts/styled-components/components/SuggestionList/wrappers.ts", "../javascripts/styled-components/components/RichSearch/wrapper.tsx"], "sourcesContent": ["import { useQuery } from '@tanstack/react-query';\nimport type { CombinedQuerySuggestion, ContentQuerySuggestion } from '../@types/QuerySuggestion';\nimport type { RequestStateQuery } from '../@types/RequestStateQuery';\nimport type { ApiResponse } from '../@types/api-response';\nimport { SUGGESTION_QUERY_COMBINED, SUGGESTION_QUERY_CONTENT } from '../Data/Article/QueryKeys';\n\nexport const useCombinedSuggestion = (\n query?: string,\n): [CombinedQuerySuggestion | undefined, RequestStateQuery] => {\n const { data, isPending, isSuccess, isError } = useQuery>({\n queryKey: [SUGGESTION_QUERY_COMBINED, query],\n queryFn: async () => {\n const response = await fetch(`${SUGGESTION_QUERY_COMBINED}?q=${encodeURIComponent(query!)}`);\n return await response.json();\n },\n retry: false,\n refetchOnWindowFocus: false,\n gcTime: Number.POSITIVE_INFINITY,\n staleTime: Number.POSITIVE_INFINITY,\n enabled: (query?.length || 0) > 2,\n });\n\n return [\n (query?.length || 0) > 2 ? data?.response : undefined,\n { isLoading: isPending, isSuccess, isError },\n ];\n};\n\nexport const useContentSuggestion = (\n query?: string,\n): [ContentQuerySuggestion[] | undefined, RequestStateQuery] => {\n const { data, isPending, isSuccess, isError } = useQuery>({\n queryKey: [SUGGESTION_QUERY_CONTENT, query],\n queryFn: async () => {\n const response = await fetch(`${SUGGESTION_QUERY_CONTENT}?q=${encodeURIComponent(query!)}`);\n return await response.json();\n },\n retry: false,\n refetchOnWindowFocus: false,\n gcTime: Number.POSITIVE_INFINITY,\n staleTime: Number.POSITIVE_INFINITY,\n enabled: (query?.length || 0) > 2,\n });\n\n return [\n (query?.length || 0) > 2 ? data?.response : undefined,\n { isLoading: isPending, isSuccess, isError },\n ];\n};\n", "import React, { useCallback, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { numberSeparator } from '../../../helpers/formats';\nimport {\n GroupHead,\n GroupLabel,\n GroupLink,\n SuggestionItem,\n SuggestionItemCount,\n SuggestionItemLabel,\n SuggestionsListWrapper,\n} from './wrappers';\n\ntype Suggestion = {\n path: string;\n label: string;\n hitCount?: number;\n};\n\nexport interface SuggestionGroup {\n suggestions: Suggestion[];\n label?: string;\n linkLabel?: string;\n linkPath?: string;\n}\n\ninterface ISuggestionList {\n groups?: SuggestionGroup[];\n focusedIndex: number | null;\n onSetFocusedIndex: (index: number | null) => void;\n onSuggestionClick?: () => void;\n}\n\nconst SuggestionsList = ({\n groups,\n focusedIndex,\n onSetFocusedIndex,\n onSuggestionClick,\n}: ISuggestionList) => {\n const navigate = useNavigate();\n const _suggestions = useMemo(\n () =>\n (groups || []).reduce((prev, curr) => {\n prev.push(...curr.suggestions);\n return prev;\n }, [] as Suggestion[]),\n [groups],\n );\n\n const onSuggestionMouseOver = useCallback(() => {\n onSetFocusedIndex(null);\n }, [onSetFocusedIndex]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (!_suggestions?.length) return;\n\n switch (e.key) {\n case 'ArrowUp':\n e.preventDefault();\n onSetFocusedIndex(\n focusedIndex !== null && focusedIndex >= 1 ? focusedIndex - 1 : _suggestions.length - 1,\n );\n break;\n\n case 'ArrowDown':\n e.preventDefault();\n onSetFocusedIndex(\n focusedIndex !== null && focusedIndex < _suggestions.length - 1 ? focusedIndex + 1 : 0,\n );\n break;\n\n case 'Enter':\n if (focusedIndex !== null && _suggestions[focusedIndex]) {\n if (onSuggestionClick) {\n onSuggestionClick();\n }\n navigate(_suggestions[focusedIndex].path);\n }\n break;\n\n default:\n onSetFocusedIndex(null);\n break;\n }\n },\n [_suggestions, focusedIndex, onSetFocusedIndex, onSuggestionClick],\n );\n\n useEffect(() => {\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [handleKeyDown]);\n\n const suggestionItems = useMemo(() => {\n let accumulatedIndex = 0;\n\n return groups?.map(({ label, linkLabel, linkPath, suggestions }, groupIndex) => {\n const groupItems = suggestions.map((suggestion, i) => {\n const index = accumulatedIndex + i;\n return (\n \n {suggestion.hitCount !== undefined ? (\n <>\n {suggestion.label}\n {numberSeparator(suggestion.hitCount)}\n \n ) : (\n suggestion.label\n )}\n \n );\n });\n\n accumulatedIndex += suggestions.length;\n\n return (\n \n {label && (\n \n {label}\n {linkLabel && linkPath && (\n \n {linkLabel}\n \n )}\n \n )}\n {groupItems}\n \n );\n });\n }, [groups, focusedIndex, onSuggestionClick, onSuggestionMouseOver]);\n\n return {suggestionItems};\n};\n\nexport default SuggestionsList;\n", "import { Link } from 'react-router-dom';\nimport styled, { css } from 'styled-components';\nimport { size } from '../../layout/helpers';\nimport { RouterLink } from '../Link';\n\ninterface ISuggestionItem {\n $focused?: boolean;\n}\n\nexport const SuggestionItem = styled(Link).withConfig({ componentId: 'sc-1uess6e-0' })`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: ${size(1.5)};\n font-size: var(--font-size-small);\n font-weight: var(--font-weight-medium);\n padding: ${size(0.5)} 0;\n position: relative;\n\n &:hover {\n &::after {\n content: \"\";\n position: absolute;\n top: 0;\n bottom: 0;\n left: ${size(-1)};\n right: ${size(-1)};\n background-color: var(--c-bg-alt);\n border-radius: ${(props) => props.theme.size.borderRadius};\n z-index: -1;\n }\n }\n\n ${({ $focused }) =>\n $focused &&\n css`\n &::before {\n content: \"\";\n position: absolute;\n top: 0;\n bottom: 0;\n left: ${size(-1)};\n right: ${size(-1)};\n background-color: var(--c-bg-alt);\n border-radius: ${(props) => props.theme.size.borderRadius};\n z-index: -1;\n }\n `}\n`;\n\nexport const SuggestionsListWrapper = styled.div.withConfig({ componentId: 'sc-1uess6e-1' })`\n border-top: 1px solid var(--c-bg-alt);\n flex: 0 0 100%;\n list-style: none;\n text-align: left;\n padding: ${size(2)} ${size(3)} ${size(3)};\n\n // Hide keyboard focus indicator when hovering with the cursor\n &:has(${SuggestionItem}:hover) {\n ${SuggestionItem}::before {\n content: none;\n }\n }\n`;\n\nexport const SuggestionItemLabel = styled.span.withConfig({ componentId: 'sc-1uess6e-2' })`\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nexport const SuggestionItemCount = styled.span.withConfig({ componentId: 'sc-1uess6e-3' })`\n font-weight: var(--font-weight-light);\n color: var(--c-text-muted);\n`;\n\nexport const GroupHead = styled.div.withConfig({ componentId: 'sc-1uess6e-4' })`\n font-size: var(--font-size-xsmall);\n line-height: var(--line-height-xsmall);\n display: flex;\n\n ${SuggestionItem} + & {\n margin-top: ${size(3)};\n }\n`;\n\nexport const GroupLabel = styled.div.withConfig({ componentId: 'sc-1uess6e-5' })`\n color: var(--c-text-muted);\n flex: 1 1 auto;\n`;\n\nexport const GroupLink = styled(RouterLink).withConfig({ componentId: 'sc-1uess6e-6' })`\n flex: 0 0 auto;\n`;\n", "import styled from 'styled-components';\n\nimport { size } from '../../layout/helpers';\nimport { ButtonReset, inputPlaceholder } from '../../layout/reset';\nimport { Button } from '../Button';\n\nexport const Wrapper = styled.div.withConfig({ componentId: 'sc-1sgvh8i-0' })`\n --_height: ${(props) => props.theme.size.inputHeight};\n --_spacing-inline-start: ${size(3)};\n --_spacing-inline-end: ${size(1.5)};\n\n color: var(--c-text-main);\n position: relative;\n z-index: 10;\n height: var(--_height);\n`;\n\nexport const Inner = styled.div.withConfig({ componentId: 'sc-1sgvh8i-1' })`\n position: relative;\n border-radius: ${size(3)};\n background-color: var(--c-bg-main);\n z-index: 1;\n\n &::before {\n content: \"\";\n position: absolute;\n inset: 0;\n background-color: inherit;\n border-radius: inherit;\n user-select: none;\n filter: drop-shadow(0px 8px 8px rgba(0, 0, 0, 0.03)) drop-shadow(0px 8px 8px rgba(0, 0, 0, 0.03)) drop-shadow(0px 5px 4px rgba(0, 0, 0, 0.09));\n z-index: -1;\n }\n`;\n\nexport const InputWrapper = styled.div.withConfig({ componentId: 'sc-1sgvh8i-2' })`\n position: relative;\n display: flex;\n align-items: center;\n height: var(--_height);\n\n ${Button} {\n margin-right: calc((var(--_height) - 34px) / 2);\n }\n`;\n\nexport const Input = styled.input.withConfig({ componentId: 'sc-1sgvh8i-3' })`\n ${inputPlaceholder};\n display: block;\n width: 100%;\n height: 100%;\n padding-top: 0;\n padding-bottom: 0;\n margin: 0;\n padding-left: var(--_spacing-inline-start);\n padding-right: var(--_spacing-inline-end);\n background-color: transparent;\n font-size: var(--font-size-input);\n border: none;\n box-shadow: none;\n appearance: none;\n\n &:focus {\n outline: none;\n }\n\n &[disabled] {\n opacity: 0.37;\n cursor: not-allowed;\n }\n`;\n\nexport const ClearButton = styled(ButtonReset).withConfig({ componentId: 'sc-1sgvh8i-4' })`\n --_hitbox: ${size(1)};\n\n margin-left: calc(var(--_spacing-inline-end) * -1);\n margin-right: var(--_hitbox);\n padding: ${size(0.5)};\n border-radius: 50%;\n background-color: var(--c-bg-alt);\n color: var(--c-text-main);\n font-size: var(--font-size-small);\n transform-origin: 50% 50%;\n transition: transform 200ms ease;\n user-select: none;\n cursor: pointer;\n\n &::before,\n &::after {\n content: \"\";\n position: absolute;\n }\n\n &::before {\n inset: 1px;\n background-color: var(--c-overlay);\n border-radius: inherit;\n mix-blend-mode: soft-light;\n opacity: 0;\n transition: opacity 200ms ease;\n }\n\n &::after {\n inset: calc(var(--_hitbox) * -1);\n }\n\n &:active {\n transform: scale(0.97);\n }\n\n &:not([disabled]):hover {\n &::before {\n opacity: 1;\n }\n }\n`;\n\nexport const Meta = styled.div.withConfig({ componentId: 'sc-1sgvh8i-5' })`\n flex-shrink: 0;\n padding-right: var(--_spacing-inline-end);\n color: var(--c-text-muted);\n font-size: ${(props) => props.theme.font.size.small};\n`;\n"], "mappings": "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", "names": ["useCombinedSuggestion", "query", "data", "isPending", "isSuccess", "isError", "useQuery", "SUGGESTION_QUERY_COMBINED", "useContentSuggestion", "SUGGESTION_QUERY_CONTENT", "import_react", "SuggestionItem", "dt", "Link", "size", "props", "$focused", "lt", "SuggestionsListWrapper", "SuggestionItemLabel", "SuggestionItemCount", "GroupHead", "GroupLabel", "GroupLink", "RouterLink", "SuggestionsList", "groups", "focusedIndex", "onSetFocusedIndex", "onSuggestionClick", "navigate", "useNavigate", "_suggestions", "prev", "curr", "onSuggestionMouseOver", "handleKeyDown", "e", "suggestionItems", "accumulatedIndex", "label", "linkLabel", "linkPath", "suggestions", "groupIndex", "groupItems", "suggestion", "i", "index", "React", "SuggestionItem", "SuggestionItemLabel", "SuggestionItemCount", "numberSeparator", "GroupHead", "GroupLabel", "GroupLink", "SuggestionsListWrapper", "SuggestionList_default", "Wrapper", "dt", "props", "size", "Inner", "InputWrapper", "Button", "Input", "inputPlaceholder", "ClearButton", "ButtonReset", "Meta"] }