diff --git a/changes/issue-8105-update-label-filter-chevron b/changes/issue-8105-update-label-filter-chevron
new file mode 100644
index 0000000000..9fc3479145
--- /dev/null
+++ b/changes/issue-8105-update-label-filter-chevron
@@ -0,0 +1 @@
+- updates label filter chevron icon to match the icon on the status filter dropdown
diff --git a/frontend/components/Icon/Icon.tsx b/frontend/components/Icon/Icon.tsx
index 23d9c1306a..15c3f437aa 100644
--- a/frontend/components/Icon/Icon.tsx
+++ b/frontend/components/Icon/Icon.tsx
@@ -1,22 +1,33 @@
-import React from "react";
-
+import React, { useMemo } from "react";
import { IconNames, ICON_MAP } from "components/icons";
import classnames from "classnames";
interface IIconProps {
name: IconNames;
+ color?: string;
className?: string;
}
const baseClass = "icon";
-const Icon = ({ name, className }: IIconProps) => {
+const Icon = ({ name, color, className }: IIconProps) => {
const classsNames = classnames(baseClass, className);
+ // createPassedProps creates a props object that we pass to the specific icon
+ // for values that are not null or undefined
+ const props = useMemo(() => {
+ const createPassedProps = () => {
+ return Object.assign({}, color === undefined ? undefined : { color });
+ };
+
+ return createPassedProps();
+ }, [color]);
+
const IconComponent = ICON_MAP[name];
+
return (
-
+
);
};
diff --git a/frontend/components/Icon/_styles.scss b/frontend/components/Icon/_styles.scss
index e69de29bb2..2be34ae007 100644
--- a/frontend/components/Icon/_styles.scss
+++ b/frontend/components/Icon/_styles.scss
@@ -0,0 +1,6 @@
+.icon {
+ // we want to ensure the icon is always centered with these styles
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
diff --git a/frontend/components/icons/ChevronDown.tsx b/frontend/components/icons/ChevronDown.tsx
new file mode 100644
index 0000000000..67a6e89854
--- /dev/null
+++ b/frontend/components/icons/ChevronDown.tsx
@@ -0,0 +1,20 @@
+import React from "react";
+
+interface IChevronDownProps {
+ color?: string;
+}
+
+const ChevronDown = ({ color = "#192147" }: IChevronDownProps) => {
+ return (
+
+ );
+};
+
+export default ChevronDown;
diff --git a/frontend/components/icons/index.ts b/frontend/components/icons/index.ts
index 9647a68921..1a23fb3afa 100644
--- a/frontend/components/icons/index.ts
+++ b/frontend/components/icons/index.ts
@@ -7,6 +7,7 @@ import LowDiskSpaceHosts from "./LowDiskSpaceHosts";
import ApplePurple from "./ApplePurple";
import LinuxGreen from "./LinuxGreen";
import WindowsBlue from "./WindowsBlue";
+import ChevronDown from "./ChevronDown";
// a mapping of the usable names of icons to the icon source.
export const ICON_MAP = {
@@ -22,6 +23,7 @@ export const ICON_MAP = {
"linux-green": LinuxGreen,
"missing-hosts": MissingHosts,
"low-disk-space-hosts": LowDiskSpaceHosts,
+ "chevron-down": ChevronDown,
};
export type IconNames = keyof typeof ICON_MAP;
diff --git a/frontend/docs/patterns.md b/frontend/docs/patterns.md
index 4b7c35d74a..c1ad1b9974 100644
--- a/frontend/docs/patterns.md
+++ b/frontend/docs/patterns.md
@@ -15,6 +15,7 @@ should be discussed within the team and documented before merged.
- [Fleet API Calls](#fleet-api-calls)
- [Page Routing](#page-routing)
- [Styles](#styles)
+ - [Icons and Images](#icons)
- [Other](#other)
## Typing
@@ -260,6 +261,8 @@ const PageOrComponent = ({
Below are a few need-to-knows about what's available in Fleet's CSS:
+
+
### Modals
1) When creating a modal with a form inside, the action buttons (cancel, save, delete, etc.) should
@@ -281,6 +284,30 @@ suffice as long as we do not go more than two levels deep. Otherwise, if states
to be used across multiple unrelated components or 3+ levels from a parent,
then the [app's context](#react-context) should be used.
+## Icons and Images
+
+### Adding Icons
+
+To add a new icon:
+
+1. create a React component for the icon in `frontend/components/icons` directory. We will add the
+ SVG here.
+2. download the icon source from Figma as an SVG file
+3. run the downloaded file through an SVG optimizer such as
+ [SVGOMG](https://jakearchibald.github.io/svgomg/) or [SVG Optimizer](https://svgoptimizer.com/)
+4. download the optimized SVG and place it in created file from step 1.
+5. import the new icon in the `frontend/components/icons/index.ts` and add it the the `ICON_MAP`
+ object. The key will be the name the icon is accessible under.
+
+The icon should now be available to use with the `Icon` component from the given key name.
+
+```tsx
+// using a new icon with the given key name 'chevron`
+
+```
+
+
+
### File size
The recommend line limit per page/component is 500 lines. This is only a recommendation.
diff --git a/frontend/pages/hosts/ManageHostsPage/components/CustomDropdownIndicator/CustomDropdownIndicator.tsx b/frontend/pages/hosts/ManageHostsPage/components/CustomDropdownIndicator/CustomDropdownIndicator.tsx
new file mode 100644
index 0000000000..b89b642cd0
--- /dev/null
+++ b/frontend/pages/hosts/ManageHostsPage/components/CustomDropdownIndicator/CustomDropdownIndicator.tsx
@@ -0,0 +1,29 @@
+import React from "react";
+import { DropdownIndicatorProps, components } from "react-select-5";
+
+import { ILabel } from "interfaces/label";
+import Icon from "components/Icon";
+
+import { IEmptyOption, IGroupOption } from "../LabelFilterSelect/helpers";
+
+const baseClass = "custom-dropdown-indicator";
+
+const CustomDropdownIndicator = (
+ props: DropdownIndicatorProps
+) => {
+ const { isFocused, selectProps } = props;
+ // no access to hover state here from react-select so that is done in the scss
+ // file of LabelFilterSelect.
+ const color = isFocused || selectProps.menuIsOpen ? "#6a67fe" : undefined;
+ return (
+
+
+
+ );
+};
+
+export default CustomDropdownIndicator;
diff --git a/frontend/pages/hosts/ManageHostsPage/components/CustomDropdownIndicator/index.ts b/frontend/pages/hosts/ManageHostsPage/components/CustomDropdownIndicator/index.ts
new file mode 100644
index 0000000000..da85947c73
--- /dev/null
+++ b/frontend/pages/hosts/ManageHostsPage/components/CustomDropdownIndicator/index.ts
@@ -0,0 +1 @@
+export { default } from "./CustomDropdownIndicator";
diff --git a/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/LabelFilterSelect.tsx b/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/LabelFilterSelect.tsx
index 1b07f59fdd..d56444fee1 100644
--- a/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/LabelFilterSelect.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/LabelFilterSelect.tsx
@@ -8,6 +8,7 @@ import { PLATFORM_LABEL_DISPLAY_NAMES } from "utilities/constants";
import CustomLabelGroupHeading from "../CustomLabelGroupHeading";
import { PLATFORM_TYPE_ICONS } from "./constants";
import { createDropdownOptions, IEmptyOption, IGroupOption } from "./helpers";
+import CustomDropdownIndicator from "../CustomDropdownIndicator";
// Extending the react-select module to add custom props we need for our custom
// group heading. More info here:
@@ -27,6 +28,8 @@ declare module "react-select-5/dist/declarations/src/Select" {
}
}
+const baseClass = "label-filter-select";
+
/** A custom option label to show in the dropdown. Only used in this dropdown
* component. You will find focus and blur handlers in this component to help
* solve the problem of changing focus between the select dropdown and the
@@ -53,8 +56,6 @@ const OptionLabel = (data: ILabel | IEmptyOption) => {
);
};
-const baseClass = "label-filter-select";
-
interface ILabelFilterSelectProps {
labels: ILabel[];
selectedLabel: ILabel | null;
@@ -158,7 +159,10 @@ const LabelFilterSelect = ({
isSearchable={false}
getOptionLabel={getOptionLabel}
getOptionValue={getOptionValue}
- components={{ GroupHeading: CustomLabelGroupHeading }}
+ components={{
+ GroupHeading: CustomLabelGroupHeading,
+ DropdownIndicator: CustomDropdownIndicator,
+ }}
labelQuery={labelQuery}
canAddNewLabels={canAddNewLabels}
onChange={handleChange}
diff --git a/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/_styles.scss b/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/_styles.scss
index 853f08dc64..6891b4073a 100644
--- a/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/_styles.scss
+++ b/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/_styles.scss
@@ -1,6 +1,16 @@
.label-filter-select {
width: 175px;
+ &:hover {
+
+ // no access to hover state from react-select in JS so this is done here.
+ .custom-dropdown-indicator {
+ & path {
+ fill: $core-vibrant-blue
+ }
+ }
+ }
+
.label-filter-select__control {
border: 1px solid $ui-fleet-blue-15;
background-color: $ui-light-grey;
@@ -108,4 +118,10 @@
margin-right: $pad-small;
}
}
+
+ &__custom-dropdown-indicator {
+ &:hover {
+ cursor: pointer;
+ }
+ }
}