Skip to content
This repository has been archived by the owner on Jul 9, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into feat/add-select-all-on-dropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
Dawn Carrasco authored and Dawn Carrasco committed Jun 21, 2024
2 parents 9c542aa + 58cb01e commit a52c9a3
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 41 deletions.
1 change: 1 addition & 0 deletions src/components/Box/Box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export interface ExtendedBoxProps extends BoxProps {
// breakpoints
sm?: customStyles;
md?: customStyles;
lp?: customStyles;
lg?: customStyles;

direction?: "row" | "column" | "row-reverse" | "column-reverse";
Expand Down
4 changes: 2 additions & 2 deletions src/components/Chip/Chip.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const StyledChip = styled.div<{
padding: 0 ${({theme}) => theme.spacing.xs};
height: ${({theme, size}) => theme.spacing[size]};
line-height: ${({theme, size}) => theme.spacing[size]};
border-radius: ${({theme}) => theme.borderRadius.minimal};
border-radius: ${({theme}) => theme.borderRadius.base};
color: ${({theme, role, priority}) => propsToColour(theme, role, priority)};
display: inline-flex;
justify-content: center;
Expand All @@ -81,7 +81,7 @@ const StyledChip = styled.div<{
props.role === "default" &&
props.priority === "low" &&
`
border: 1px solid ${props.theme.core.border.borderMedium};
border: 1px solid ${props.theme.core.border.borderLight};
`}
${(props) => addCustomStyles(props)};
Expand Down
21 changes: 21 additions & 0 deletions src/components/Dropdown/Dropdown.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,25 @@ describe("Dropdown Component", () => {
expect(getByText("inline-loading")).toBeInTheDocument();
});
});

it("shows inputvalue in input if provided", async () => {
const {getByRole} = render(
<Dropdown label="Dropdown" options={options} inputValue="Super cool option" />
);
const input = getByRole("textbox");

expect(input).toHaveValue("Super cool option");
});

it("fires event if user types in Input if onInputChange is provided", async () => {
const onInputChange = jest.fn();
const {getByRole} = render(
<Dropdown label="Dropdown" options={options} onInputChange={onInputChange} />
);
const input = getByRole("textbox");

fireEvent.change(input, {target: {value: "Super cool option"}});

expect(onInputChange).toHaveBeenCalledWith(expect.anything());
});
});
83 changes: 49 additions & 34 deletions src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import Popover from "../Popover";
import {ListItem} from "../List";
import Chip from "../Chip";
import {faChevronDown, faSearch} from "@fortawesome/pro-regular-svg-icons";
import {customStyles} from "../../core/styleFunctions";

export interface Option {
id: string | number;
text: string;
selected?: boolean;
category?: string;
startAdornment?: React.ReactNode;
endAdornment?: React.ReactNode;
}

Expand All @@ -31,6 +33,9 @@ export interface DropdownProps {
hasClearSelection?: boolean;
hasSelectAll?: boolean;
hasSearch?: boolean;
inputValue?: string;
onInputChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
endAdornment?: React.ReactNode;
onChange?: (selectedValue: any, previouslySelected: boolean) => void;
onClearSelection?: () => void;
onSelectAll?: () => void;
Expand All @@ -39,6 +44,7 @@ export interface DropdownProps {
"data-cy"?: string;
loadingIndicator?: React.ReactNode;
selectedIndicator?: React.ReactNode;
cs?: customStyles;
}

/**
Expand All @@ -60,6 +66,9 @@ const Dropdown = ({
hasClearSelection = false,
hasSelectAll = false,
hasSearch = false,
inputValue,
onInputChange,
endAdornment,
onChange = () => {},
onClearSelection = () => {},
onSelectAll = () => {},
Expand All @@ -68,11 +77,11 @@ const Dropdown = ({
"data-cy": dataCy,
loadingIndicator,
selectedIndicator,
cs,
}: DropdownProps) => {
const popRef = useRef<any>(null);
const [showPopover, setShowPopover] = useState(false);
// eslint-disable-next-line
const [value, setValue] = useState(defaultValue);
const [searchTerm, setSearchTerm] = useState("");
const selectedCount = [
...new Set(
Expand Down Expand Up @@ -105,59 +114,64 @@ const Dropdown = ({
setShowPopover(false);
}}
>
<Box>
<Box cs={cs}>
<Input
data-testid={dataTestId}
data-cy={dataCy}
error={error}
onChange={onInputChange}
onClick={() => {
setShowPopover(true);
}}
endAdornment={
<Box
cs={{
display: "inline-flex",
gap: "spacing.xs",
alignItems: "center",
paddingLeft: "spacing.sm",
background: "white",
}}
>
{hasSelectedCount ? (
!notSelectedCount ? (
// needed to disable because eslint is looking for aria attribute role
// eslint-disable-next-line
<Chip priority="low" role="primary" size="md">
ALL
</Chip>
) : selectedCount ? (
// needed to disable because eslint is looking for aria attribute role
// eslint-disable-next-line
<Chip priority="low" role="primary" size="md">
{selectedCount}
</Chip>
) : null
) : null}
<SvgIcon
icon={faChevronDown}
onClick={() => {
setShowPopover(true);
endAdornment || (
<Box
cs={{
display: "inline-flex",
gap: "spacing.xs",
alignItems: "center",
paddingLeft: "spacing.sm",
background: "white",
}}
/>
</Box>
>
{hasSelectedCount ? (
!notSelectedCount ? (
// needed to disable because eslint is looking for aria attribute role
// eslint-disable-next-line
<Chip priority="low" role="primary" size="md">
ALL
</Chip>
) : selectedCount ? (
// needed to disable because eslint is looking for aria attribute role
// eslint-disable-next-line
<Chip priority="low" role="primary" size="md">
{selectedCount}
</Chip>
) : null
) : null}
<SvgIcon
icon={faChevronDown}
onClick={() => {
setShowPopover(true);
}}
/>
</Box>
)
}
fullWidth
ref={popRef}
label={label}
placeholder={placeholder}
value={
multipleSelect
typeof inputValue === "string"
? inputValue
: multipleSelect
? selectedCount
? label
: ""
: options?.find((item: any) => item?.id === defaultValue)?.text || ""
}
readOnly={true}
readOnly={typeof inputValue !== "string"}
/>
{showPopover ? (
<Popover
Expand Down Expand Up @@ -239,6 +253,7 @@ const Dropdown = ({
data-testid={`dropdown-option-item-${x?.id || idx}`}
data-cy={`dropdown-option-item-${x?.id || idx}`}
button
startAdornment={x?.startAdornment}
endAdornment={
x?.endAdornment ||
((multipleSelect && x?.selected) ||
Expand Down
12 changes: 7 additions & 5 deletions src/core/styleFunctions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ type ShorthandCSS = {
type breakpoints = {
sm?: CSS.Properties | ShorthandCSS;
md?: CSS.Properties | ShorthandCSS;
lp?: CSS.Properties | ShorthandCSS;
lg?: CSS.Properties | ShorthandCSS;
};

type keysTypes = "sm" | "md" | "lg";
type keysTypes = "sm" | "md" | "lp" | "lg";

const values: {sm: number; md: number; lg: number} = {
sm: 0, // tablet
md: 600, // small laptop
const values: {sm: number; md: number; lp: number; lg: number} = {
sm: 0, // mobile
md: 600, // tablet
lp: 960, // small laptop
lg: 1360, // desktop 1360
};

Expand Down Expand Up @@ -106,7 +108,7 @@ const numberToSpacingMap = {
export type customStyles = CSS.Properties | breakpoints | ShorthandCSS;

const defaultBreakpoints = {
keys: ["sm", "md", "lg"],
keys: ["sm", "md", "lp", "lg"],
up: (key: keysTypes) => `@media (min-width:${values[key]}px)`,
};

Expand Down

0 comments on commit a52c9a3

Please sign in to comment.