change label filter dropdown icon match status dropdown and extend icon component (#8337)
This commit is contained in:
@@ -0,0 +1 @@
|
||||
- updates label filter chevron icon to match the icon on the status filter dropdown
|
||||
@@ -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 (
|
||||
<div className={classsNames}>
|
||||
<IconComponent />
|
||||
<IconComponent {...props} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from "react";
|
||||
|
||||
interface IChevronDownProps {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
const ChevronDown = ({ color = "#192147" }: IChevronDownProps) => {
|
||||
return (
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="m8.751 10.891 4.144-4.297a.385.385 0 0 0 0-.528l-.927-.957a.345.345 0 0 0-.502 0L8.5 8.189l-2.966-3.08a.345.345 0 0 0-.502 0l-.927.957a.385.385 0 0 0 0 .528l4.144 4.297c.14.145.363.145.502 0Z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChevronDown;
|
||||
@@ -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;
|
||||
|
||||
@@ -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`
|
||||
<Icon name="chevron" />
|
||||
```
|
||||
|
||||
|
||||
|
||||
### File size
|
||||
|
||||
The recommend line limit per page/component is 500 lines. This is only a recommendation.
|
||||
|
||||
+29
@@ -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<ILabel | IEmptyOption, false, IGroupOption>
|
||||
) => {
|
||||
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 (
|
||||
<components.DropdownIndicator {...props} className={baseClass}>
|
||||
<Icon
|
||||
name="chevron-down"
|
||||
color={color}
|
||||
className={`${baseClass}__icon`}
|
||||
/>
|
||||
</components.DropdownIndicator>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomDropdownIndicator;
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from "./CustomDropdownIndicator";
|
||||
+7
-3
@@ -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}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user