Fleet UI: Checkbox and accessibility styling, tab through select targets (#22943)
This commit is contained in:
@@ -155,7 +155,6 @@ const SelectTargets = ({
|
||||
const { isPremiumTier, isOnGlobalTeam, currentUser } = useContext(AppContext);
|
||||
|
||||
const [labels, setLabels] = useState<ILabelsByType | null>(null);
|
||||
const [inputTabIndex, setInputTabIndex] = useState<number | null>(null);
|
||||
const [searchText, setSearchText] = useState("");
|
||||
const [debouncedSearchText, setDebouncedSearchText] = useState("");
|
||||
const [isDebouncing, setIsDebouncing] = useState(false);
|
||||
@@ -263,12 +262,6 @@ const SelectTargets = ({
|
||||
labelsSummary && setLabels(parseLabels(labelsSummary));
|
||||
}, [labelsSummary]);
|
||||
|
||||
useEffect(() => {
|
||||
if (inputTabIndex === null && labelsSummary && teams) {
|
||||
setInputTabIndex(labelsSummary.length + teams.length || 0);
|
||||
}
|
||||
}, [inputTabIndex, labelsSummary, teams]);
|
||||
|
||||
useEffect(() => {
|
||||
setIsDebouncing(true);
|
||||
debounceSearch(searchText);
|
||||
@@ -485,7 +478,6 @@ const SelectTargets = ({
|
||||
autofocus
|
||||
searchResultsTableConfig={resultsTableConfig}
|
||||
selectedHostsTableConifg={selectedHostsTableConfig}
|
||||
tabIndex={inputTabIndex || 0}
|
||||
searchText={searchText}
|
||||
searchResults={searchResults || []}
|
||||
isTargetsLoading={isFetchingSearchResults || isDebouncing}
|
||||
|
||||
@@ -91,7 +91,6 @@ const TargetsInput = ({
|
||||
type="search"
|
||||
iconSvg="search"
|
||||
value={searchText}
|
||||
tabIndex={tabIndex}
|
||||
iconPosition="start"
|
||||
label={label}
|
||||
placeholder={placeholder}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
.target-pill-selector {
|
||||
padding: $pad-small;
|
||||
background-color: $core-white;
|
||||
border: none;
|
||||
box-shadow: inset 0 0 0 1px $ui-fleet-black-25;
|
||||
border-radius: $border-radius-medium;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: $pad-small;
|
||||
|
||||
&:not(:last-of-type) {
|
||||
margin-right: $pad-small;
|
||||
}
|
||||
img {
|
||||
max-width: 12px;
|
||||
}
|
||||
.plus-icon {
|
||||
padding-right: 3px;
|
||||
}
|
||||
.selector-name {
|
||||
margin-left: 8px;
|
||||
font-size: $x-small;
|
||||
flex: 1;
|
||||
}
|
||||
.selector-count {
|
||||
margin-left: 8px;
|
||||
font-size: $xxx-small;
|
||||
font-weight: $bold;
|
||||
}
|
||||
&[data-selected="true"] {
|
||||
background-color: $ui-vibrant-blue-10;
|
||||
box-shadow: inset 0 0 0 1px $core-vibrant-blue;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: inset 0 0 0 1px $core-vibrant-blue-over;
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: inset 0 0 0 1px $core-vibrant-blue-down;
|
||||
}
|
||||
|
||||
// When tabbing
|
||||
&:focus-visible {
|
||||
outline: 2px solid $ui-vibrant-blue-25;
|
||||
outline-offset: 1px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ $shadow-transition-width: 10px;
|
||||
background-attachment: local, local, scroll, scroll;
|
||||
// End shadow
|
||||
}
|
||||
|
||||
|
||||
// applied to same element as data-table__table while loading
|
||||
&__no-rows {
|
||||
min-height: 272px;
|
||||
@@ -68,6 +68,12 @@ $shadow-transition-width: 10px;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleaner when tabbing
|
||||
a:focus-visible {
|
||||
outline-offset: 0;
|
||||
border-radius: $border-radius-medium;
|
||||
}
|
||||
}
|
||||
|
||||
thead {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import React, { ReactNode } from "react";
|
||||
import React, { ReactNode, KeyboardEvent, useEffect, useRef } from "react";
|
||||
import classnames from "classnames";
|
||||
import { noop, pick } from "lodash";
|
||||
|
||||
import FormField from "components/forms/FormField";
|
||||
import { IFormFieldProps } from "components/forms/FormField/FormField";
|
||||
import TooltipWrapper from "components/TooltipWrapper";
|
||||
import Icon from "components/Icon";
|
||||
|
||||
const baseClass = "fleet-checkbox";
|
||||
|
||||
@@ -17,14 +18,17 @@ export interface ICheckboxProps {
|
||||
disabled?: boolean;
|
||||
name?: string;
|
||||
onChange?: any; // TODO: meant to be an event; figure out type for this
|
||||
onBlur?: any;
|
||||
value?: boolean;
|
||||
onBlur?: (event: React.FocusEvent<HTMLDivElement>) => void;
|
||||
value?: boolean | null;
|
||||
wrapperClassName?: string;
|
||||
indeterminate?: boolean;
|
||||
parseTarget?: boolean;
|
||||
tooltipContent?: React.ReactNode;
|
||||
isLeftLabel?: boolean;
|
||||
helpText?: React.ReactNode;
|
||||
/** Use in table action only
|
||||
* Do not use on forms as enter key reserved for submit */
|
||||
enableEnterToCheck?: boolean;
|
||||
}
|
||||
|
||||
const Checkbox = (props: ICheckboxProps) => {
|
||||
@@ -36,22 +40,52 @@ const Checkbox = (props: ICheckboxProps) => {
|
||||
name,
|
||||
onChange = noop,
|
||||
onBlur = noop,
|
||||
value,
|
||||
value = false,
|
||||
wrapperClassName,
|
||||
indeterminate,
|
||||
indeterminate = false,
|
||||
parseTarget,
|
||||
tooltipContent,
|
||||
isLeftLabel,
|
||||
helpText,
|
||||
enableEnterToCheck = false,
|
||||
} = props;
|
||||
|
||||
const handleChange = () => {
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (inputRef.current) {
|
||||
inputRef.current.indeterminate = indeterminate;
|
||||
}
|
||||
}, [indeterminate]);
|
||||
|
||||
const handleChange = (
|
||||
event: React.MouseEvent | React.KeyboardEvent
|
||||
): void => {
|
||||
event.preventDefault();
|
||||
if (readOnly || disabled) return;
|
||||
|
||||
// If indeterminate, set to true; otherwise, toggle the current value
|
||||
const newValue = indeterminate || !value;
|
||||
|
||||
if (parseTarget) {
|
||||
// Returns both name and value
|
||||
return onChange({ name, value: !value });
|
||||
onChange({ name, value: newValue });
|
||||
} else {
|
||||
onChange(newValue);
|
||||
}
|
||||
|
||||
return onChange(!value);
|
||||
// Update the hidden input
|
||||
if (inputRef.current) {
|
||||
inputRef.current.checked = newValue;
|
||||
}
|
||||
};
|
||||
|
||||
/** Manual implementation of spacebar toggling checkboxes (default behavior)
|
||||
* since we're using a custom div instead of a native checkbox
|
||||
* Enter key intended to toggle table checkboxes only */
|
||||
const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {
|
||||
if (event.key === " " || (enableEnterToCheck && event.key === "Enter")) {
|
||||
handleChange(event);
|
||||
}
|
||||
};
|
||||
|
||||
const checkBoxClass = classnames(
|
||||
@@ -60,12 +94,6 @@ const Checkbox = (props: ICheckboxProps) => {
|
||||
baseClass
|
||||
);
|
||||
|
||||
const checkBoxTickClass = classnames(`${baseClass}__tick`, {
|
||||
[`${baseClass}__tick--read-only`]: readOnly || disabled,
|
||||
[`${baseClass}__tick--disabled`]: disabled,
|
||||
[`${baseClass}__tick--indeterminate`]: indeterminate,
|
||||
});
|
||||
|
||||
const checkBoxLabelClass = classnames(checkBoxClass, {
|
||||
[`${baseClass}__label--read-only`]: readOnly || disabled,
|
||||
[`${baseClass}__label--disabled`]: disabled,
|
||||
@@ -77,21 +105,40 @@ const Checkbox = (props: ICheckboxProps) => {
|
||||
type: "checkbox",
|
||||
} as IFormFieldProps;
|
||||
|
||||
const getIconName = () => {
|
||||
if (indeterminate) return "checkbox-indeterminate";
|
||||
if (value) return "checkbox";
|
||||
return "checkbox-unchecked";
|
||||
};
|
||||
|
||||
return (
|
||||
<FormField {...formFieldProps}>
|
||||
<>
|
||||
<label htmlFor={name} className={checkBoxLabelClass}>
|
||||
<input
|
||||
checked={value}
|
||||
className={`${baseClass}__input`}
|
||||
disabled={readOnly || disabled}
|
||||
id={name}
|
||||
name={name}
|
||||
onChange={handleChange}
|
||||
onBlur={onBlur}
|
||||
type="checkbox"
|
||||
<label htmlFor={name}>
|
||||
<input
|
||||
type="checkbox"
|
||||
ref={inputRef}
|
||||
name={name}
|
||||
checked={value || undefined}
|
||||
onChange={noop} // Empty onChange to avoid React warning
|
||||
disabled={disabled || readOnly}
|
||||
style={{ display: "none" }} // Hide the input
|
||||
id={name}
|
||||
/>
|
||||
<div
|
||||
role="checkbox"
|
||||
aria-checked={indeterminate ? "mixed" : value || undefined}
|
||||
aria-readonly={readOnly}
|
||||
aria-disabled={disabled}
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
className={checkBoxLabelClass}
|
||||
onClick={handleChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
onBlur={onBlur}
|
||||
>
|
||||
<Icon
|
||||
name={getIconName()}
|
||||
className={`${baseClass}__icon ${baseClass}__icon--${getIconName()}`}
|
||||
/>
|
||||
<span className={checkBoxTickClass} />
|
||||
{tooltipContent ? (
|
||||
<span className={`${baseClass}__label-tooltip tooltip`}>
|
||||
<TooltipWrapper
|
||||
@@ -102,10 +149,10 @@ const Checkbox = (props: ICheckboxProps) => {
|
||||
</TooltipWrapper>
|
||||
</span>
|
||||
) : (
|
||||
<span className={`${baseClass}__label`}>{children} </span>
|
||||
<span className={`${baseClass}__label`}>{children}</span>
|
||||
)}
|
||||
</label>
|
||||
</>
|
||||
</div>
|
||||
</label>
|
||||
</FormField>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,115 +4,50 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&__input {
|
||||
opacity: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 2px;
|
||||
|
||||
&:focus + .fleet-checkbox__tick {
|
||||
&::after {
|
||||
border-color: $core-vibrant-blue;
|
||||
&:hover:not(.fleet-checkbox__label--disabled) {
|
||||
svg {
|
||||
.checkbox-state {
|
||||
stroke: $core-vibrant-blue-over;
|
||||
fill: $core-vibrant-blue-over;
|
||||
}
|
||||
}
|
||||
|
||||
&:checked + .fleet-checkbox__tick {
|
||||
&::after {
|
||||
background-color: $core-vibrant-blue;
|
||||
border: solid 2px $core-vibrant-blue;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::after {
|
||||
background-color: $core-vibrant-blue-over;
|
||||
border: solid 2px $core-vibrant-blue-over;
|
||||
}
|
||||
}
|
||||
|
||||
&--read-only {
|
||||
&::after {
|
||||
@include disabled-checkbox;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::after {
|
||||
@include disabled-checkbox;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&::before {
|
||||
@include position(absolute, 50% null null 50%);
|
||||
transform: rotate(45deg);
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
width: 7px;
|
||||
height: 13px;
|
||||
margin: -8px 0 0 -3px;
|
||||
border: 2px solid $core-white;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
content: "";
|
||||
z-index: 9;
|
||||
.checkbox-unchecked-state {
|
||||
stroke: $core-vibrant-blue-over;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__tick {
|
||||
@include size(20px);
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
|
||||
&::after {
|
||||
@include size(20px);
|
||||
transition: border 75ms ease-in-out, background 75ms ease-in-out;
|
||||
border-radius: $border-radius;
|
||||
border: solid 2px $ui-fleet-black-25;
|
||||
content: "";
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
background-color: $core-white;
|
||||
visibility: visible;
|
||||
}
|
||||
&:hover {
|
||||
&::after {
|
||||
border: solid 2px $core-vibrant-blue-over;
|
||||
// During click only
|
||||
&:active:not(.fleet-checkbox__label--disabled) {
|
||||
svg {
|
||||
.checkbox-state {
|
||||
stroke: $core-vibrant-blue-down;
|
||||
fill: $core-vibrant-blue-down;
|
||||
}
|
||||
.checkbox-unchecked-state {
|
||||
stroke: $core-vibrant-blue-down;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
&::after {
|
||||
background-color: $ui-fleet-black-25;
|
||||
}
|
||||
cursor: default;
|
||||
// When tabbing
|
||||
&:focus-visible:not(.fleet-checkbox__label--disabled) {
|
||||
outline: none;
|
||||
|
||||
svg {
|
||||
outline: 2px solid $ui-vibrant-blue-25;
|
||||
outline-offset: 1px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&--indeterminate {
|
||||
&::after {
|
||||
background-color: $core-vibrant-blue;
|
||||
border: solid 1px $core-vibrant-blue;
|
||||
&--disabled {
|
||||
svg {
|
||||
.checkbox-state {
|
||||
stroke: $ui-fleet-black-25;
|
||||
fill: $ui-fleet-black-25;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::after {
|
||||
&::after {
|
||||
background-color: $core-vibrant-blue-over;
|
||||
border: solid 1px $core-vibrant-blue-over;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&::before {
|
||||
@include position(absolute, 50% null null 50%);
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
width: 10px;
|
||||
margin: -1px 0 0 -5px;
|
||||
border: 2px solid $core-white;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
content: "";
|
||||
.checkbox-unchecked-state {
|
||||
stroke: $ui-fleet-black-25;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,6 +60,16 @@
|
||||
|
||||
&--disabled {
|
||||
color: $ui-fleet-black-50;
|
||||
|
||||
svg {
|
||||
.checkbox-state {
|
||||
stroke: $ui-fleet-black-25;
|
||||
fill: $ui-fleet-black-25;
|
||||
}
|
||||
.checkbox-unchecked-state {
|
||||
stroke: $ui-fleet-black-25;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,13 +89,8 @@
|
||||
flex-direction: row-reverse; // Switches the text to the left side of checkbox as all checkboxes are now display flex
|
||||
|
||||
.fleet-checkbox {
|
||||
&__input {
|
||||
float: right;
|
||||
}
|
||||
|
||||
&__tick {
|
||||
left: initial;
|
||||
right: -8px;
|
||||
&__icon {
|
||||
padding-left: $pad-small;
|
||||
}
|
||||
|
||||
&__label {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import React from "react";
|
||||
import { COLORS, Colors } from "styles/var/colors";
|
||||
|
||||
interface ICheckboxProps {
|
||||
color?: Colors;
|
||||
}
|
||||
|
||||
const Checkbox = ({ color = "core-fleet-blue" }: ICheckboxProps) => {
|
||||
return (
|
||||
<svg width="16" height="17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
className="checkbox-state"
|
||||
x="1"
|
||||
y="1.5"
|
||||
width="14"
|
||||
height="14"
|
||||
rx="3"
|
||||
fill={COLORS[color]}
|
||||
stroke={COLORS[color]}
|
||||
strokeWidth="2"
|
||||
/>
|
||||
<g clipPath="url(#checkbox)">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M3.933 8.647c-.016 0-.033 0-.066.016a.828.828 0 0 1-.184-.066c.05-.033.134-.017.25.05Zm8.448-4.482c-.434-.233-.917.216-1.2.483-.65.633-1.2 1.366-1.816 2.032-.683.734-1.316 1.467-2.016 2.183-.4.4-.833.833-1.1 1.334-.6-.584-1.116-1.217-1.782-1.733-.483-.367-1.283-.634-1.267.25.034 1.149 1.05 2.382 1.8 3.165.316.334.733.683 1.216.7.583.033 1.183-.667 1.533-1.05.616-.666 1.117-1.416 1.683-2.099.733-.9 1.483-1.783 2.199-2.7.45-.566 1.866-1.965.75-2.565Z"
|
||||
fill="#fff"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="checkbox">
|
||||
<path
|
||||
fill="#fff"
|
||||
transform="translate(3.2 4.1)"
|
||||
d="M0 0h9.6v8.8H0z"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default Checkbox;
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from "react";
|
||||
import { COLORS, Colors } from "styles/var/colors";
|
||||
|
||||
interface ICheckboxIndeterminateProps {
|
||||
color?: Colors;
|
||||
}
|
||||
|
||||
const CheckboxIndeterminate = ({
|
||||
color = "core-fleet-blue",
|
||||
}: ICheckboxIndeterminateProps) => {
|
||||
return (
|
||||
<svg width="16" height="17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
className="checkbox-state"
|
||||
x="1"
|
||||
y="1.5"
|
||||
width="14"
|
||||
height="14"
|
||||
rx="3"
|
||||
fill={COLORS[color]}
|
||||
stroke={COLORS[color]}
|
||||
strokeWidth="2"
|
||||
/>
|
||||
<rect x="3" y="7.5" width="10" height="2" rx="1" fill="#fff" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default CheckboxIndeterminate;
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
import { COLORS, Colors } from "styles/var/colors";
|
||||
|
||||
interface ICheckboxUncheckedProps {
|
||||
color?: Colors;
|
||||
}
|
||||
|
||||
const CheckboxUnchecked = ({
|
||||
color = "ui-fleet-black-25",
|
||||
}: ICheckboxUncheckedProps) => {
|
||||
return (
|
||||
<svg width="16" height="17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
className="checkbox-unchecked-state"
|
||||
x="1"
|
||||
y="1.5"
|
||||
width="14"
|
||||
height="14"
|
||||
rx="3"
|
||||
fill="#fff"
|
||||
stroke={COLORS[color]}
|
||||
strokeWidth="2"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default CheckboxUnchecked;
|
||||
@@ -3,6 +3,9 @@ import ArrowInternalLink from "./ArrowInternalLink";
|
||||
import Calendar from "./Calendar";
|
||||
import CalendarCheck from "./CalendarCheck";
|
||||
import Check from "./Check";
|
||||
import Checkbox from "./Checkbox";
|
||||
import CheckboxIndeterminate from "./CheckboxIndeterminate";
|
||||
import CheckboxUnchecked from "./CheckboxUnchecked";
|
||||
import ChevronLeft from "./ChevronLeft";
|
||||
import ChevronRight from "./ChevronRight";
|
||||
import ChevronUp from "./ChevronUp";
|
||||
@@ -73,6 +76,9 @@ export const ICON_MAP = {
|
||||
"chevron-up": ChevronUp,
|
||||
"chevron-down": ChevronDown,
|
||||
check: Check,
|
||||
checkbox: Checkbox,
|
||||
"checkbox-indeterminate": CheckboxIndeterminate,
|
||||
"checkbox-unchecked": CheckboxUnchecked,
|
||||
columns: Columns,
|
||||
disable: Disable,
|
||||
close: Close,
|
||||
|
||||
+2
-2
@@ -92,7 +92,7 @@ const generateTableHeaders = (
|
||||
indeterminate: props.indeterminate,
|
||||
onChange: () => cellProps.toggleAllRowsSelected(),
|
||||
};
|
||||
return <Checkbox {...checkboxProps} />;
|
||||
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
||||
},
|
||||
Cell: (cellProps: ICellProps): JSX.Element => {
|
||||
const props = cellProps.row.getToggleRowSelectedProps();
|
||||
@@ -100,7 +100,7 @@ const generateTableHeaders = (
|
||||
value: props.checked,
|
||||
onChange: () => cellProps.row.toggleRowSelected(),
|
||||
};
|
||||
return <Checkbox {...checkboxProps} />;
|
||||
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
||||
},
|
||||
disableHidden: true,
|
||||
},
|
||||
|
||||
@@ -76,6 +76,11 @@
|
||||
@media (max-width: 825px) {
|
||||
padding: 15px 18px;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline-offset: -3px; // Cleaner when tabbing
|
||||
border-radius: $border-radius-medium;
|
||||
}
|
||||
}
|
||||
|
||||
&__logo-wrapper {
|
||||
|
||||
@@ -93,10 +93,6 @@
|
||||
width: calc(90% - 50px);
|
||||
margin-bottom: $pad-medium;
|
||||
}
|
||||
|
||||
&__disabled-usage-statistics-checkbox {
|
||||
@include disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,11 +72,7 @@ const Statistics = ({
|
||||
name="enableUsageStatistics"
|
||||
value={isPremiumTier ? true : enableUsageStatistics} // Set to true for all premium customers
|
||||
parseTarget
|
||||
wrapperClassName={
|
||||
isPremiumTier
|
||||
? `${baseClass}__disabled-usage-statistics-checkbox`
|
||||
: ""
|
||||
}
|
||||
disabled={isPremiumTier}
|
||||
>
|
||||
Enable usage statistics
|
||||
</Checkbox>
|
||||
|
||||
@@ -90,7 +90,7 @@ const allHostTableHeaders: IHostTableColumnConfig[] = [
|
||||
indeterminate: props.indeterminate,
|
||||
onChange: () => cellProps.toggleAllRowsSelected(),
|
||||
};
|
||||
return <Checkbox {...checkboxProps} />;
|
||||
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
||||
},
|
||||
Cell: (cellProps: ISelectionCellProps) => {
|
||||
const props = cellProps.row.getToggleRowSelectedProps();
|
||||
@@ -98,7 +98,7 @@ const allHostTableHeaders: IHostTableColumnConfig[] = [
|
||||
value: props.checked,
|
||||
onChange: () => cellProps.row.toggleRowSelected(),
|
||||
};
|
||||
return <Checkbox {...checkboxProps} />;
|
||||
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
||||
},
|
||||
disableHidden: true,
|
||||
},
|
||||
|
||||
@@ -76,7 +76,7 @@ const generateTableHeaders = (): IDataColumn[] => {
|
||||
indeterminate: props.indeterminate,
|
||||
onChange: () => cellProps.toggleAllRowsSelected(),
|
||||
};
|
||||
return <Checkbox {...checkboxProps} />;
|
||||
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
||||
},
|
||||
Cell: (cellProps: ICellProps): JSX.Element => {
|
||||
const props = cellProps.row.getToggleRowSelectedProps();
|
||||
@@ -84,7 +84,7 @@ const generateTableHeaders = (): IDataColumn[] => {
|
||||
value: props.checked,
|
||||
onChange: () => cellProps.row.toggleRowSelected(),
|
||||
};
|
||||
return <Checkbox {...checkboxProps} />;
|
||||
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
||||
},
|
||||
disableHidden: true,
|
||||
},
|
||||
|
||||
+2
-2
@@ -299,7 +299,7 @@ const generateTableHeaders = (
|
||||
const checkboxProps = viewingTeamPolicies
|
||||
? teamCheckboxProps
|
||||
: regularCheckboxProps;
|
||||
return <Checkbox {...checkboxProps} />;
|
||||
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
||||
},
|
||||
Cell: (cellProps: ICellProps): JSX.Element => {
|
||||
const inheritedPolicy = cellProps.row.original.team_id === null;
|
||||
@@ -314,7 +314,7 @@ const generateTableHeaders = (
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return <Checkbox {...checkboxProps} />;
|
||||
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
||||
},
|
||||
disableHidden: true,
|
||||
});
|
||||
|
||||
@@ -57,42 +57,6 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.target-pill-selector {
|
||||
padding: $pad-small;
|
||||
background-color: $core-white;
|
||||
border: none;
|
||||
box-shadow: inset 0 0 0 1px $ui-fleet-black-25;
|
||||
border-radius: $border-radius-medium;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: $pad-small;
|
||||
|
||||
&:not(:last-of-type) {
|
||||
margin-right: $pad-small;
|
||||
}
|
||||
img {
|
||||
max-width: 12px;
|
||||
}
|
||||
.plus-icon {
|
||||
padding-right: 3px;
|
||||
}
|
||||
.selector-name {
|
||||
margin-left: 8px;
|
||||
font-size: $x-small;
|
||||
flex: 1;
|
||||
}
|
||||
.selector-count {
|
||||
margin-left: 8px;
|
||||
font-size: $xxx-small;
|
||||
font-weight: $bold;
|
||||
}
|
||||
&[data-selected="true"] {
|
||||
background-color: $ui-vibrant-blue-10;
|
||||
box-shadow: inset 0 0 0 1px $core-vibrant-blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&__targets-button-wrap {
|
||||
|
||||
+2
-2
@@ -274,7 +274,7 @@ const generateTableHeaders = ({
|
||||
(row.original.team_id ?? undefined) === currentTeamId,
|
||||
});
|
||||
|
||||
return <Checkbox {...checkboxProps} />;
|
||||
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
||||
},
|
||||
Cell: (cellProps: ICellProps): JSX.Element => {
|
||||
const isInheritedQuery =
|
||||
@@ -290,7 +290,7 @@ const generateTableHeaders = ({
|
||||
onChange: () => row.toggleRowSelected(),
|
||||
};
|
||||
// v4.35.0 Any team admin or maintainer now can add, edit, delete their team's queries
|
||||
return <Checkbox {...checkboxProps} />;
|
||||
return <Checkbox {...checkboxProps} enableEnterToCheck />;
|
||||
},
|
||||
disableHidden: true,
|
||||
});
|
||||
|
||||
@@ -25,42 +25,6 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.target-pill-selector {
|
||||
padding: $pad-small;
|
||||
background-color: $core-white;
|
||||
border: none;
|
||||
box-shadow: inset 0 0 0 1px $ui-fleet-black-25;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: $pad-small;
|
||||
|
||||
&:not(:last-of-type) {
|
||||
margin-right: $pad-small;
|
||||
}
|
||||
img {
|
||||
max-width: 12px;
|
||||
}
|
||||
.plus-icon {
|
||||
padding-right: 3px;
|
||||
}
|
||||
.selector-name {
|
||||
margin-left: 8px;
|
||||
font-size: $x-small;
|
||||
flex: 1;
|
||||
}
|
||||
.selector-count {
|
||||
margin-left: 8px;
|
||||
font-size: $xxx-small;
|
||||
font-weight: $bold;
|
||||
}
|
||||
&[data-selected="true"] {
|
||||
background-color: $ui-vibrant-blue-10;
|
||||
box-shadow: inset 0 0 0 1px $core-vibrant-blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&__targets-button-wrap {
|
||||
|
||||
@@ -147,6 +147,7 @@ $max-width: 2560px;
|
||||
outline-offset: 3px;
|
||||
outline-style: solid;
|
||||
outline-width: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user