diff --git a/site/src/components/Filter/filter.tsx b/site/src/components/Filter/filter.tsx index 1ea5a5df209aa..1a4b40c5292a5 100644 --- a/site/src/components/Filter/filter.tsx +++ b/site/src/components/Filter/filter.tsx @@ -32,6 +32,12 @@ import { Loader } from "components/Loader/Loader"; import { useDebouncedFunction } from "hooks/debounce"; import { useFilterMenu } from "./menu"; import type { BaseOption } from "./options"; +import { + Search, + SearchEmpty, + SearchInput, + searchStyles, +} from "components/Menu/Search"; export type PresetFilter = { name: string; @@ -489,7 +495,7 @@ export const FilterSearchMenu = ({ onQueryChange={menu.setQuery} renderOption={(option) => ( { menu.selectOption(option); @@ -576,7 +582,6 @@ function SearchMenu({ }: SearchMenuProps) { const menuListRef = useRef(null); const searchInputRef = useRef(null); - const theme = useTheme(); return ( ({ onQueryChange(""); }} css={{ - "& .MuiPaper-root": { - width: 320, - padding: 0, - }, + "& .MuiPaper-root": searchStyles.content, }} // Disabled this so when we clear the filter and do some sorting in the // search items it does not look strange. Github removes exit transitions @@ -606,44 +608,16 @@ function SearchMenu({ } }} > -
  • - - + { onQueryChange(e.target.value); }} - css={{ - height: "100%", - border: 0, - background: "none", - width: "100%", - marginLeft: 16, - outline: 0, - "&::placeholder": { - color: theme.palette.text.secondary, - }, - }} /> -
  • +
  • ({ options.length > 0 ? ( options.map(renderOption) ) : ( -
    - No results -
    + ) ) : ( diff --git a/site/src/components/Menu/Search.tsx b/site/src/components/Menu/Search.tsx new file mode 100644 index 0000000000000..833f247fb3229 --- /dev/null +++ b/site/src/components/Menu/Search.tsx @@ -0,0 +1,100 @@ +import SearchOutlined from "@mui/icons-material/SearchOutlined"; +// eslint-disable-next-line no-restricted-imports -- use it to have the component prop +import Box, { BoxProps } from "@mui/material/Box"; +import { Interpolation, Theme, useTheme } from "@mui/material/styles"; +import visuallyHidden from "@mui/utils/visuallyHidden"; +import { FC, HTMLAttributes, InputHTMLAttributes, forwardRef } from "react"; + +export const Search = forwardRef( + ({ children, ...boxProps }, ref) => { + const theme = useTheme(); + + return ( + + + {children} + + ); + }, +); + +type SearchInputProps = InputHTMLAttributes & { + label?: string; +}; + +export const SearchInput = forwardRef( + ({ label, ...inputProps }, ref) => { + const theme = useTheme(); + + return ( + <> + + + + ); + }, +); + +export const SearchEmpty: FC> = ({ + children = "Not found", + ...props +}) => { + const theme = useTheme(); + + return ( +
    + {children} +
    + ); +}; + +export const searchStyles = { + content: { + width: 320, + padding: 0, + borderRadius: 4, + }, +} satisfies Record>; diff --git a/site/src/pages/WorkspacesPage/WorkspacesButton.tsx b/site/src/pages/WorkspacesPage/WorkspacesButton.tsx index a50510a0ccaa7..ce61aaddca785 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesButton.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesButton.tsx @@ -11,7 +11,6 @@ import AddIcon from "@mui/icons-material/AddOutlined"; import OpenIcon from "@mui/icons-material/OpenInNewOutlined"; import { Loader } from "components/Loader/Loader"; import { OverflowY } from "components/OverflowY/OverflowY"; -import { EmptyState } from "components/EmptyState/EmptyState"; import { Avatar } from "components/Avatar/Avatar"; import { SearchBox } from "./WorkspacesSearchBox"; import { @@ -19,6 +18,7 @@ import { PopoverContent, PopoverTrigger, } from "components/Popover/Popover"; +import { SearchEmpty, searchStyles } from "components/Menu/Search"; const ICON_SIZE = 18; @@ -43,17 +43,15 @@ export const WorkspacesButton: FC = ({ let emptyState: ReactNode = undefined; if (templates?.length === 0) { emptyState = ( - - Create one now. - - } - /> + + No templates yet.{" "} + + Create one now. + + ); } else if (processed.length === 0) { - emptyState = ; + emptyState = No templates found; } return ( @@ -63,7 +61,12 @@ export const WorkspacesButton: FC = ({ {children} - + setSearchTerm(newValue)} diff --git a/site/src/pages/WorkspacesPage/WorkspacesSearchBox.tsx b/site/src/pages/WorkspacesPage/WorkspacesSearchBox.tsx index d9c8a8ab0de8e..09274b743d58a 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesSearchBox.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesSearchBox.tsx @@ -11,9 +11,7 @@ import { forwardRef, useId, } from "react"; -import SearchIcon from "@mui/icons-material/SearchOutlined"; -import { visuallyHidden } from "@mui/utils"; -import { useTheme } from "@emotion/react"; +import { Search, SearchInput } from "components/Menu/Search"; interface SearchBoxProps extends InputHTMLAttributes { label?: string; @@ -35,39 +33,12 @@ export const SearchBox = forwardRef(function SearchBox( } = props; const hookId = useId(); - const theme = useTheme(); - const inputId = `${hookId}-${SearchBox.name}-input`; return ( -
    -
    - -
    - - - - + onValueChange(e.target.value)} - css={{ - height: "100%", - border: 0, - background: "none", - width: "100%", - outline: 0, - "&::placeholder": { - color: theme.palette.text.secondary, - }, - }} /> -
    + ); });