Skip to content

Commit

Permalink
style(inputsearch): change default html clear icon (#607)
Browse files Browse the repository at this point in the history
* style(inputsearch): change default html clear icon

* refactor(inputsearch): turn autocomplete off + replace deprecated onKeyPress with onKeyDown

* refactor(inputsearch): remove default clear icon and add a xMark icon as end adornment to input

* fix(inputsearch): add onchange events for the new inputClear icon

* docs(inputsearch): add comments for context

* fix(inputsearch): fix clear icon hover state

* fix(autocomplete): update test snapshots

* style(dropdown): fix popper width
  • Loading branch information
masoudmanson authored Sep 22, 2023
1 parent e9d4df0 commit dddcd34
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ exports[`<Autocomplete /> Default story renders snapshot 1`] = `
Search by label
</label>
<div
class="MuiFormControl-root MuiTextField-root css-zhsnsf-MuiFormControl-root-MuiTextField-root"
class="MuiFormControl-root MuiTextField-root css-1rjsjzb-MuiFormControl-root-MuiTextField-root"
>
<div
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-sizeSmall MuiInputBase-adornedEnd css-o9k5xi-MuiInputBase-root-MuiOutlinedInput-root"
Expand All @@ -39,9 +39,11 @@ exports[`<Autocomplete /> Default story renders snapshot 1`] = `
value=""
/>
<div
class="MuiInputAdornment-root MuiInputAdornment-positionEnd MuiInputAdornment-outlined MuiInputAdornment-sizeSmall css-1laqsz7-MuiInputAdornment-root"
class="MuiInputAdornment-root MuiInputAdornment-positionEnd MuiInputAdornment-outlined MuiInputAdornment-sizeSmall css-g8kzra-MuiInputAdornment-root"
>
<button
aria-label="search-button"
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeMedium css-1fqpm4w-MuiButtonBase-root-MuiIconButton-root"
tabindex="0"
type="button"
Expand All @@ -51,7 +53,7 @@ exports[`<Autocomplete /> Default story renders snapshot 1`] = `
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-1q6hio5-MuiSvgIcon-root"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-tr2xv3-MuiSvgIcon-root"
data-file-name="IconSearchSmall"
data-testid="IconSearchSmall"
fillcontrast="white"
Expand Down
41 changes: 38 additions & 3 deletions packages/components/src/core/Autocomplete/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
AutocompleteInputChangeReason,
AutocompleteRenderInputParams,
AutocompleteRenderOptionState,
InputAdornment,
AutocompleteProps as MuiAutocompleteProps,
Popper,
PopperProps,
Expand All @@ -13,6 +12,7 @@ import { noop } from "src/common/utils";
import ButtonIcon from "../ButtonIcon";
import { IconProps } from "../Icon";
import { InputSearchProps } from "../InputSearch";
import { StyledInputAdornment } from "../InputSearch/style";
import MenuItem, { IconNameToSmallSizes } from "../MenuItem";
import {
InputBaseWrapper,
Expand Down Expand Up @@ -171,13 +171,34 @@ const Autocomplete = <
*/
...params.InputProps.ref,
endAdornment: (
<InputAdornment position="end">
<StyledInputAdornment position="end">
{/**
* (masoudmansdon): Because the Autocomplete component overrides the
* InputSearch's endAdornment, we must also include the clear IconButton here.
*/}
{inputValue && (
<ButtonIcon
aria-label="clear-button"
className="input-search-clear-icon"
onClick={clearInput}
sdsType="primary"
sdsSize="small"
sdsIconProps={{
sdsType: "iconButton",
}}
sdsIcon="xMark"
/>
)}
<ButtonIcon
aria-label="search-button"
sdsType="secondary"
sdsSize="small"
sdsIconProps={{
sdsType: "interactive",
}}
sdsIcon="search"
/>
</InputAdornment>
</StyledInputAdornment>
),
inputProps: params.inputProps,
}}
Expand Down Expand Up @@ -217,6 +238,20 @@ const Autocomplete = <
/>
);

function clearInput() {
setInputValue("");
/**
* (masoudmanson): Because we are manually firing this event,
* we must build a onChange event to transmit the updated value to onChange listeners.
*/
if (onInputChange)
onInputChange(
{ target: { value: "" } } as React.ChangeEvent<HTMLInputElement>,
"",
"clear"
);
}

function defaultGetOptionLabel(
option: T | AutocompleteFreeSoloValueMapping<FreeSolo>
): string {
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/core/Autocomplete/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export const StyledPaper = styled(Paper)`
const shadows = getShadows(props);
return `
padding: ${spacings?.s}px 0 0 ${spacings?.s}px ;
padding: ${spacings?.s}px 0 0 ${spacings?.s}px;
background-color: white;
border: ${borders?.gray[100]};
border-radius: ${corners?.m}px;
Expand Down
14 changes: 13 additions & 1 deletion packages/components/src/core/Dropdown/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ const Dropdown = (props: Args): JSX.Element => {
onChange={noop}
options={GITHUB_LABELS}
DropdownMenuProps={{
PopperBaseProps: {
sx: { width: "300px" },
},
groupBy: (option: DefaultDropdownMenuOption) =>
option.section as string,
}}
Expand Down Expand Up @@ -150,7 +153,7 @@ export const InsideModal = {
skip: true,
},
},
render: function InsideModalComponent(): JSX.Element {
render: function InsideModalComponent(props: Args): JSX.Element {
const [value, setValue] = useState<
DefaultDropdownMenuOption | DefaultDropdownMenuOption[] | null
>([GITHUB_LABELS[0], GITHUB_LABELS[1]]);
Expand All @@ -168,6 +171,7 @@ export const InsideModal = {
value={value}
multiple
InputDropdownProps={{ sdsStyle: "square" }}
{...props}
/>
</Dialog>
);
Expand Down Expand Up @@ -206,6 +210,9 @@ const ControlledDropdownDemo = (props: Args): JSX.Element => {
onChange={handleChange}
data-testid="dropdown"
DropdownMenuProps={{
PopperBaseProps: {
sx: { width: "300px" },
},
groupBy: (option: DefaultDropdownMenuOption) =>
option.section as string,
title: "Github Labels",
Expand Down Expand Up @@ -244,6 +251,11 @@ const TestDemo = (props: Args): JSX.Element => {
label="Click Target"
onChange={noop}
options={GITHUB_LABELS}
DropdownMenuProps={{
PopperBaseProps: {
sx: { width: "300px" },
},
}}
{...props}
data-testid="dropdown"
/>
Expand Down
51 changes: 43 additions & 8 deletions packages/components/src/core/InputSearch/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {
InputAdornment,
TextFieldProps as RawTextFieldSearchProps,
} from "@mui/material";
import { TextFieldProps as RawTextFieldSearchProps } from "@mui/material";
import React, { forwardRef, useState } from "react";
import ButtonIcon from "../ButtonIcon";
import { InputSearchExtraProps, StyledLabel, StyledSearchBase } from "./style";
import {
InputSearchExtraProps,
StyledInputAdornment,
StyledLabel,
StyledSearchBase,
} from "./style";

export interface AccessibleInputSearchProps {
label: string;
Expand Down Expand Up @@ -50,6 +52,23 @@ const InputSearch = forwardRef<HTMLDivElement, InputSearchProps>(
if (onChange) onChange(event);
};

const clearInput = () => {
setValue("");
setHasValue(false);

if (handleSubmit) handleSubmit("");

/**
* (masoudmanson): Because we are manually firing this event,
* we must build a onChange event to transmit the updated value to onChange listeners.
*/
if (onChange) {
onChange({
target: { value: "" },
} as React.ChangeEvent<HTMLInputElement>);
}
};

const localHandleSubmit = () => {
if (handleSubmit) handleSubmit(value);
};
Expand Down Expand Up @@ -77,7 +96,18 @@ const InputSearch = forwardRef<HTMLDivElement, InputSearchProps>(
// passed to mui Input
InputProps={{
endAdornment: (
<InputAdornment position="end">
<StyledInputAdornment position="end">
<ButtonIcon
aria-label="clear-button"
className="input-search-clear-icon"
onClick={clearInput}
sdsType="primary"
sdsSize="small"
sdsIconProps={{
sdsType: "iconButton",
}}
sdsIcon="xMark"
/>
<ButtonIcon
aria-label="search-button"
onClick={localHandleSubmit}
Expand All @@ -88,7 +118,7 @@ const InputSearch = forwardRef<HTMLDivElement, InputSearchProps>(
}}
sdsIcon="search"
/>
</InputAdornment>
</StyledInputAdornment>
),
}}
type="search"
Expand All @@ -100,8 +130,13 @@ const InputSearch = forwardRef<HTMLDivElement, InputSearchProps>(
sdsStyle={sdsStyle}
sdsStage={hasValue ? "userInput" : "default"}
onChange={handleChange}
onKeyPress={handleKeyPress}
onKeyDown={handleKeyPress}
intent={intent}
/**
* (masoudmanson): This prevents the browser's default auto completion
* menu from being displayed for the InputSearch.
*/
autoComplete="off"
{...rest}
/>
</>
Expand Down
33 changes: 29 additions & 4 deletions packages/components/src/core/InputSearch/style.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { css, SerializedStyles } from "@emotion/react";
import {
buttonBaseClasses,
InputAdornment,
inputAdornmentClasses,
inputBaseClasses,
outlinedInputClasses,
Expand All @@ -21,6 +23,7 @@ export interface InputSearchExtraProps extends CommonThemeProps {
intent?: "default" | "error" | "warning";
sdsStyle?: "rounded" | "square";
sdsStage?: "default" | "userInput";
value?: string;
}

const sdsPropNames = ["sdsStyle", "sdsStage", "intent", "handleSubmit"];
Expand Down Expand Up @@ -104,7 +107,7 @@ export const StyledSearchBase = styled(TextField, {
},
})`
${(props: InputSearchExtraProps) => {
const { intent, disabled, sdsStyle } = props;
const { intent, disabled, sdsStyle, value } = props;
const spacings = getSpaces(props);
const borders = getBorders(props);
const colors = getColors(props);
Expand All @@ -116,14 +119,29 @@ export const StyledSearchBase = styled(TextField, {
min-width: 120px;
display: block;
[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none;
appearance: none;
}
& .input-search-clear-icon {
opacity: 0;
margin-right: ${spacings?.s}px;
}
.${outlinedInputClasses.root} {
.${outlinedInputClasses.notchedOutline} {
border: ${borders?.gray[400]};
}
&:hover .input-search-clear-icon,
&:focus-within .input-search-clear-icon {
opacity: ${value ? 1 : 0};
}
}
.${inputBaseClasses.inputSizeSmall} {
padding: ${spacings?.xs}px 0 ${spacings?.xs}px ${spacings?.l}px;
padding: ${spacings?.xs}px ${spacings?.l}px;
height: 34px;
box-sizing: border-box;
background-color: #fff;
Expand All @@ -139,8 +157,11 @@ export const StyledSearchBase = styled(TextField, {
border: ${borders?.primary[400]};
}
.${inputAdornmentClasses.root} svg {
color: ${colors?.primary[400]};
.${inputAdornmentClasses.root} .${buttonBaseClasses.root}:last-of-type {
cursor: default;
svg {
color: ${colors?.primary[400]};
}
}
}
Expand All @@ -151,3 +172,7 @@ export const StyledSearchBase = styled(TextField, {
`;
}}
`;

export const StyledInputAdornment = styled(InputAdornment)`
position: relative;
`;

0 comments on commit dddcd34

Please sign in to comment.