github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/HelpSearchBar.tsx (about) 1 import { InputAdornment } from "@material-ui/core" 2 import { InputProps as StandardInputProps } from "@material-ui/core/Input/Input" 3 import React, { ChangeEvent, KeyboardEvent, useState } from "react" 4 import styled from "styled-components" 5 import { ReactComponent as CloseSvg } from "./assets/svg/close.svg" 6 import { ReactComponent as SearchSvg } from "./assets/svg/search.svg" 7 import { 8 InstrumentedButton, 9 InstrumentedTextField, 10 } from "./instrumentedComponents" 11 import { 12 Color, 13 Font, 14 FontSize, 15 mixinResetButtonStyle, 16 SizeUnit, 17 } from "./style-helpers" 18 19 export function searchDocs(query: string) { 20 const docsSearchUrl = new URL("https://docs.tilt.dev/search") 21 docsSearchUrl.searchParams.set("q", query) 22 docsSearchUrl.searchParams.set("utm_source", "tiltui") 23 window.open(docsSearchUrl) 24 } 25 26 export const HelpSearchBarTextField = styled(InstrumentedTextField)` 27 & .MuiOutlinedInput-root { 28 border-radius: ${SizeUnit(0.5)}; 29 background-color: ${Color.white}; 30 31 & fieldset { 32 border-color: 1px solid ${Color.gray40}; 33 } 34 &:hover fieldset { 35 border: 1px solid ${Color.gray40}; 36 } 37 &.Mui-focused fieldset { 38 border: 1px solid ${Color.gray40}; 39 } 40 & .MuiOutlinedInput-input { 41 padding: ${SizeUnit(0.2)}; 42 } 43 } 44 45 margin-top: ${SizeUnit(0.4)}; 46 margin-bottom: ${SizeUnit(0.4)}; 47 48 & .MuiInputBase-input { 49 font-family: ${Font.monospace}; 50 color: ${Color.gray40}; 51 font-size: ${FontSize.small}; 52 } 53 ` 54 55 export const ClearHelpSearchBarButton = styled(InstrumentedButton)` 56 ${mixinResetButtonStyle}; 57 display: flex; 58 align-items: center; 59 ` 60 61 export function HelpSearchBar(props: { className?: string }) { 62 const [searchValue, setSearchValue] = useState("") 63 64 let inputProps: Partial<StandardInputProps> = { 65 startAdornment: ( 66 <InputAdornment position="start"> 67 <SearchSvg fill={Color.grayLightest} /> 68 </InputAdornment> 69 ), 70 "aria-label": "Search Tilt Docs", 71 } 72 73 function handleKeyPress(e: KeyboardEvent) { 74 if ("Enter" === e.key) { 75 searchDocs(searchValue) 76 setSearchValue("") 77 } 78 } 79 80 function handleChange(e: ChangeEvent<HTMLInputElement>) { 81 const { value } = e.target 82 setSearchValue(value) 83 } 84 85 // only show the "x" to clear if there's any input to clear 86 if (searchValue.length) { 87 const onClearClick = () => setSearchValue("") 88 89 inputProps.endAdornment = ( 90 <InputAdornment position="end"> 91 <ClearHelpSearchBarButton 92 onClick={onClearClick} 93 analyticsName="ui.web.clearHelpSearchBar" 94 aria-label="Clear search term" 95 > 96 <CloseSvg role="presentation" fill={Color.grayLightest} /> 97 </ClearHelpSearchBarButton> 98 </InputAdornment> 99 ) 100 } 101 102 return ( 103 <HelpSearchBarTextField 104 className={props.className} 105 value={searchValue} 106 placeholder="Search Tilt Docs..." 107 InputProps={inputProps} 108 variant="outlined" 109 analyticsName="ui.web.helpSearchBar" 110 onKeyPress={handleKeyPress} 111 onChange={handleChange} 112 /> 113 ) 114 }