From 95f4207d38626be67aa188174e8213aa22dcd1aa Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Tue, 11 Jun 2024 19:53:53 +0000 Subject: [PATCH 1/3] refactor(site): refactor filter search field --- site/src/components/Filter/filter.tsx | 56 +++--------------- .../SearchField/SearchField.stories.tsx | 45 ++++++++++++++ .../components/SearchField/SearchField.tsx | 58 +++++++++++++++++++ 3 files changed, 112 insertions(+), 47 deletions(-) create mode 100644 site/src/components/SearchField/SearchField.stories.tsx create mode 100644 site/src/components/SearchField/SearchField.tsx diff --git a/site/src/components/Filter/filter.tsx b/site/src/components/Filter/filter.tsx index 8335408c11733..866bfc27d0c17 100644 --- a/site/src/components/Filter/filter.tsx +++ b/site/src/components/Filter/filter.tsx @@ -1,19 +1,13 @@ import { useTheme } from "@emotion/react"; import CheckOutlined from "@mui/icons-material/CheckOutlined"; -import CloseOutlined from "@mui/icons-material/CloseOutlined"; import KeyboardArrowDown from "@mui/icons-material/KeyboardArrowDown"; import OpenInNewOutlined from "@mui/icons-material/OpenInNewOutlined"; -import SearchOutlined from "@mui/icons-material/SearchOutlined"; import Button, { type ButtonProps } from "@mui/material/Button"; import Divider from "@mui/material/Divider"; -import IconButton from "@mui/material/IconButton"; -import InputAdornment from "@mui/material/InputAdornment"; import Menu, { type MenuProps } from "@mui/material/Menu"; import MenuItem from "@mui/material/MenuItem"; import MenuList from "@mui/material/MenuList"; import Skeleton, { type SkeletonProps } from "@mui/material/Skeleton"; -import TextField from "@mui/material/TextField"; -import Tooltip from "@mui/material/Tooltip"; import { type FC, type ReactNode, @@ -35,6 +29,7 @@ import { SearchInput, searchStyles, } from "components/Search/Search"; +import { SearchField } from "components/SearchField/SearchField"; import { useDebouncedFunction } from "hooks/debounce"; import type { useFilterMenu } from "./menu"; import type { BaseOption } from "./options"; @@ -199,7 +194,6 @@ export const Filter: FC = ({ }, [filter.query]); const shouldDisplayError = hasError(error) && isApiValidationError(error); - const hasFilterQuery = filter.query !== ""; return (
= ({ learnMoreLabel2={learnMoreLabel2} learnMoreLink2={learnMoreLink2} /> - = ({ ? getValidationErrorMessage(error) : undefined } - size="small" + placeholder="Search..." + value={queryCopy} + aria-label="Filter" + onChange={(query) => { + setQueryCopy(query); + filter.debounceUpdate(query); + }} InputProps={{ - "aria-label": "Filter", - name: "query", - placeholder: "Search...", - value: queryCopy, ref: textboxInputRef, - onChange: (e) => { - setQueryCopy(e.target.value); - filter.debounceUpdate(e.target.value); - }, onBlur: () => { if (queryCopy !== filter.query) { setQueryCopy(filter.query); @@ -258,40 +250,10 @@ export const Filter: FC = ({ "&:hover": { zIndex: 2, }, - "& input::placeholder": { - color: theme.palette.text.secondary, - }, - "& .MuiInputAdornment-root": { - marginLeft: 0, - }, "&.Mui-error": { zIndex: 3, }, }, - startAdornment: ( - - - - ), - endAdornment: hasFilterQuery && ( - - - { - filter.update(""); - }} - > - - - - - ), }} />
diff --git a/site/src/components/SearchField/SearchField.stories.tsx b/site/src/components/SearchField/SearchField.stories.tsx new file mode 100644 index 0000000000000..254de5fe637eb --- /dev/null +++ b/site/src/components/SearchField/SearchField.stories.tsx @@ -0,0 +1,45 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { userEvent, within } from "@storybook/test"; +import { useState } from "react"; +import { SearchField } from "./SearchField"; + +const meta: Meta = { + title: "components/SearchField", + component: SearchField, + args: { + placeholder: "Search...", + }, + render: function StatefulWrapper(args) { + const [value, setValue] = useState(args.value); + return ; + }, +}; + +export default meta; +type Story = StoryObj; + +export const Empty: Story = {}; + +export const DefaultValue: Story = { + args: { + value: "owner:me", + }, +}; + +export const TypeValue: Story = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const input = canvas.getByRole("textbox"); + await userEvent.type(input, "owner:me"); + }, +}; + +export const ClearValue: Story = { + args: { + value: "owner:me", + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await userEvent.click(canvas.getByRole("button", { name: "Clear field" })); + }, +}; diff --git a/site/src/components/SearchField/SearchField.tsx b/site/src/components/SearchField/SearchField.tsx new file mode 100644 index 0000000000000..b987acd0e5dbb --- /dev/null +++ b/site/src/components/SearchField/SearchField.tsx @@ -0,0 +1,58 @@ +import { useTheme } from "@emotion/react"; +import CloseOutlined from "@mui/icons-material/CloseOutlined"; +import SearchOutlined from "@mui/icons-material/SearchOutlined"; +import IconButton from "@mui/material/IconButton"; +import InputAdornment from "@mui/material/InputAdornment"; +import TextField, { type TextFieldProps } from "@mui/material/TextField"; +import Tooltip from "@mui/material/Tooltip"; +import visuallyHidden from "@mui/utils/visuallyHidden"; +import type { FC } from "react"; + +export type SearchFieldProps = Omit & { + onChange: (query: string) => void; +}; + +export const SearchField: FC = ({ + value = "", + onChange, + InputProps, + ...textFieldProps +}) => { + const theme = useTheme(); + return ( + onChange(e.target.value)} + InputProps={{ + startAdornment: ( + + + + ), + endAdornment: value !== "" && ( + + + { + onChange(""); + }} + > + + Clear field + + + + ), + ...InputProps, + }} + {...textFieldProps} + /> + ); +}; From 4fa88aa278f9d11f64efd4deeaf3d6013f93be57 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Wed, 12 Jun 2024 12:42:13 +0000 Subject: [PATCH 2/3] Improve icon names --- site/src/components/SearchField/SearchField.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/site/src/components/SearchField/SearchField.tsx b/site/src/components/SearchField/SearchField.tsx index b987acd0e5dbb..9e81b74e972ac 100644 --- a/site/src/components/SearchField/SearchField.tsx +++ b/site/src/components/SearchField/SearchField.tsx @@ -1,6 +1,6 @@ import { useTheme } from "@emotion/react"; -import CloseOutlined from "@mui/icons-material/CloseOutlined"; -import SearchOutlined from "@mui/icons-material/SearchOutlined"; +import CloseIcon from "@mui/icons-material/CloseOutlined"; +import SearchIcon from "@mui/icons-material/SearchOutlined"; import IconButton from "@mui/material/IconButton"; import InputAdornment from "@mui/material/InputAdornment"; import TextField, { type TextFieldProps } from "@mui/material/TextField"; @@ -27,7 +27,7 @@ export const SearchField: FC = ({ InputProps={{ startAdornment: ( - = ({ onChange(""); }} > - + Clear field From d3258fed1aef00d0accd1abd7e3714acc53f6a51 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Wed, 12 Jun 2024 12:59:55 +0000 Subject: [PATCH 3/3] Fix aria label --- site/src/components/Filter/filter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/components/Filter/filter.tsx b/site/src/components/Filter/filter.tsx index 866bfc27d0c17..91d8d78ee1cf4 100644 --- a/site/src/components/Filter/filter.tsx +++ b/site/src/components/Filter/filter.tsx @@ -230,13 +230,13 @@ export const Filter: FC = ({ } placeholder="Search..." value={queryCopy} - aria-label="Filter" onChange={(query) => { setQueryCopy(query); filter.debounceUpdate(query); }} InputProps={{ ref: textboxInputRef, + "aria-label": "Filter", onBlur: () => { if (queryCopy !== filter.query) { setQueryCopy(filter.query); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy