Fleet UI: PR #49292 follow-up — buttons, 8px gaps, focus ring (#50049)

This commit is contained in:
RachelElysia
2026-07-28 13:52:48 -07:00
committed by GitHub
parent 360e4b74ff
commit f7c2cf4106
60 changed files with 58 additions and 109 deletions
@@ -237,6 +237,7 @@ const ActionsDropdown = ({
...provided,
display: "flex",
flexDirection: "row",
gap: "8px",
width: "max-content",
// Need minHeight to override default
minHeight: variant === "secondary" ? "28px" : "32px", // Match button height
@@ -277,9 +278,17 @@ const ActionsDropdown = ({
}),
// Same ring Button's :focus-visible draws — only for keyboard tabbing,
// never a mouse click (see isKeyboardFocus above).
//
// Drawn INSIDE the control (via outline + negative offset) rather than
// as an outset box-shadow. An outset shadow renders as a full-contrast
// 1px halo on the page background, and for the bordered `secondary`
// variant it stacks against the existing 1px grey border → reads as a
// ~2px band. Sitting inside the box overlays the border pixel and
// matches Button's own `::after` focus ring visual weight.
...(state.isFocused &&
isKeyboardFocus && {
boxShadow: `0 0 0 1px ${COLORS["core-fleet-black"]}`,
outline: `1px solid ${COLORS["core-fleet-black"]}`,
outlineOffset: "-1px",
}),
}),
placeholder: (provided, state) => ({
@@ -293,7 +302,7 @@ const ActionsDropdown = ({
variant === "subdued" || variant === "secondary" ? "600" : undefined,
lineHeight: "normal",
paddingLeft: 0,
marginTop: "1px",
margin: 0,
...(state.isDisabled && {
filter: "grayscale(0.5)",
opacity: 0.5,
@@ -11,7 +11,7 @@
align-items: center;
button .children-wrapper {
gap: $pad-xsmall;
gap: $pad-small;
.actions-dropdown__icon svg {
transition: transform 0.25s ease;
@@ -57,7 +57,6 @@ const CertificateInstallDetailsModal = ({
hideText="Details"
caretPosition="after"
onClick={() => setShowDetails((prev) => !prev)}
variant="secondary"
/>
{showDetails && (
<Textarea label="Error details:" variant="code">
@@ -324,7 +324,6 @@ export const SoftwareInstallDetailsModal = ({
hideText="Details"
caretPosition="after"
onClick={toggleInstallDetails}
variant="secondary"
/>
)}
{showInstallDetails &&
@@ -473,7 +473,6 @@ export const SoftwareIpaInstallDetailsModal = ({
hideText="Details"
caretPosition="after"
onClick={toggleInstallDetails}
variant="secondary"
/>
{showInstallDetails && (
<>
@@ -507,7 +506,6 @@ export const SoftwareIpaInstallDetailsModal = ({
hideText="Details"
caretPosition="after"
onClick={toggleInstallDetails}
variant="secondary"
/>
{showInstallDetails && (
<Textarea label="Error details:" variant="code">
@@ -241,7 +241,6 @@ export const SoftwareScriptDetailsModal = ({
hideText="Details"
caretPosition="after"
onClick={toggleInstallDetails}
variant="secondary"
/>
)}
{showInstallDetails && swInstallResult?.output && (
@@ -248,7 +248,6 @@ const SoftwareUninstallDetailsModal = ({
hideText="Details"
caretPosition="after"
onClick={toggleDetails}
variant="secondary"
/>
)}
{showDetails && uninstallResult?.script_contents && (
@@ -535,7 +535,6 @@ export const VppInstallDetailsModal = ({
hideText="Details"
caretPosition="after"
onClick={toggleInstallDetails}
variant="secondary"
/>
{showInstallDetails && (
<>
@@ -569,7 +568,6 @@ export const VppInstallDetailsModal = ({
hideText="Details"
caretPosition="after"
onClick={toggleInstallDetails}
variant="secondary"
/>
{showInstallDetails && (
<Textarea label="Error details:" variant="code">
@@ -382,7 +382,6 @@ const PlatformWrapper = ({
showText="Plain osquery"
caretPosition="after"
onClick={() => setShowPlainOsquery((prev) => !prev)}
variant="secondary"
/>
{showPlainOsquery && (
<>
@@ -29,7 +29,7 @@ const BackButton = ({
return (
<Button variant="subdued" onClick={onClick} className={classes}>
<Icon name="chevron-left" color="ui-fleet-black-50" />
<Icon name="chevron-left" />
<span>{text}</span>
</Button>
);
@@ -469,7 +469,6 @@ const SelectTargets = ({
showText="Show more"
hideText="Show less"
isShowing={isListExpanded}
variant="secondary"
/>
</div>
)}
+2 -2
View File
@@ -118,7 +118,7 @@
>* {
display: flex;
justify-content: space-between;
gap: $pad-medium;
gap: $gap-action-elements;
align-items: center;
}
@@ -143,5 +143,5 @@
display: flex;
flex-direction: row-reverse;
margin-top: $pad-xlarge;
gap: $pad-medium;
gap: $gap-action-elements;
}
+1 -1
View File
@@ -12,7 +12,7 @@
&__secondary-buttons_wrapper {
display: flex;
justify-content: space-between;
gap: $pad-medium;
gap: $gap-action-elements;
align-items: center;
}
@@ -40,7 +40,7 @@ const Pagination = ({
onClick={onPrevPage}
className={`${baseClass}__pagination-button`}
>
<Icon name="chevron-left" color="ui-fleet-black-75" /> Previous
<Icon name="chevron-left" /> Previous
</Button>
<Button
variant="subdued"
@@ -231,25 +231,23 @@ $shadow-transition-width: 16px;
display: flex;
justify-content: space-between;
align-items: center;
gap: $gap-table-elements;
p {
margin: 0 $pad-medium 0 0;
margin: 0;
font-weight: $regular;
span {
font-weight: $bold;
}
}
button {
margin-right: $pad-medium;
}
}
&__inner-left,
&__inner-right {
display: flex;
align-items: center;
gap: $gap-table-elements;
}
}
@@ -1,7 +1,7 @@
.table-container {
display: flex;
flex-direction: column;
gap: $gap-table-elements;
gap: $gap-page-component-inner;
// Container is responsive design used when customControl is rendered
.container {
@@ -120,13 +120,6 @@
}
}
// Compound selector (not just &__table-action-button) so this reliably
// beats the base .button class's own padding regardless of SCSS compile
// order a tie at equal specificity bit us before (Scripts row gap).
&__table-action-button.button {
padding: $pad-small;
}
&__header-left {
display: flex;
width: 100%;
@@ -1,14 +1,12 @@
.action-buttons {
display: flex;
button {
margin-left: $pad-medium;
}
gap: $gap-action-elements;
&__secondary-buttons {
display: none;
@media (min-width: $break-md) {
display: flex;
gap: $gap-action-elements;
}
}
@@ -15,8 +15,6 @@ export interface IRevealButtonProps {
tooltipContent?: React.ReactNode;
disabledTooltipContent?: React.ReactNode;
onClick?: (evt: React.MouseEvent<HTMLButtonElement>) => void;
/** Default: "secondary" */
variant?: "secondary" | "subdued";
}
const baseClass = "reveal-button";
@@ -32,7 +30,6 @@ const RevealButton = ({
tooltipContent,
disabledTooltipContent,
onClick,
variant = "secondary",
}: IRevealButtonProps): JSX.Element => {
const classNames = classnames(baseClass, className);
@@ -70,7 +67,7 @@ const RevealButton = ({
const button = (
<Button
variant={variant}
variant="secondary"
className={classNames}
onClick={onClick}
autofocus={autofocus}
@@ -1,7 +1,6 @@
.reveal-button .children-wrapper {
display: inline-flex;
align-items: center;
padding: $pad-small $pad-xxsmall; // larger clickable area
min-width: max-content;
.reveal-button__caret svg {
@@ -137,7 +137,7 @@ const LoginForm = ({
variant="subdued"
className="back-link"
>
<Icon name="chevron-left" color="ui-fleet-black-75" />
<Icon name="chevron-left" />
Back to login
</Button>
<h1>Check your email</h1>
+1 -1
View File
@@ -8,7 +8,7 @@ interface IChevronProps {
}
const ChevronLeft = ({
color = "core-fleet-black",
color = "ui-fleet-black-75",
size = "medium",
}: IChevronProps) => {
return (
@@ -12,7 +12,7 @@
display: grid;
grid-template-areas: "type date sort";
grid-template-columns: 4fr 3fr 3fr;
gap: $pad-medium;
gap: $gap-table-elements;
}
&__type-filter-dropdown {
@@ -483,7 +483,7 @@ const ChartCard = ({
<Button
type="button"
variant="subdued"
className={`${baseClass}__settings-btn`}
size="small"
ariaLabel="Configure chart filters"
onClick={() => openFilterModal()}
>
@@ -168,7 +168,6 @@ const SoftwareFilters = ({
hideText="Advanced options"
caretPosition="after"
onClick={() => setShowAdvanced((prev) => !prev)}
variant="secondary"
/>
{showAdvanced && (
@@ -125,21 +125,6 @@
}
}
&__settings-btn {
// Button variant="subdued" applies a 36px height that would make the
// chart-card header taller than HostsEnrolledCard's bare h2 next door.
// Shrink to content height so headers match.
display: flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
cursor: pointer;
color: $ui-fleet-black-75;
height: auto !important;
padding: 0 !important;
}
&__chart-container {
min-height: 280px;
display: flex;
@@ -171,7 +171,6 @@ const ActivityFeedAutomationsModal = ({
onClick={() => {
setShowExamplePayload(!showExamplePayload);
}}
variant="secondary"
/>
{showExamplePayload && renderExamplePayload()}
<div className="modal-cta-wrap">
@@ -237,7 +237,6 @@ const DiskEncryption = ({
hideText="Advanced options"
caretPosition="after"
onClick={() => setShowAdvancedOptions(!showAdvancedOptions)}
variant="secondary"
/>
{showAdvancedOptions && (
<Checkbox
@@ -40,7 +40,7 @@
&__actions {
display: flex;
align-items: center;
gap: $pad-medium;
gap: $gap-action-elements;
}
&__details {
@@ -62,7 +62,6 @@ const BootstrapAdvancedOptions = ({
hideText="Advanced options"
caretPosition="after"
onClick={() => setShowAdvancedOptions(!showAdvancedOptions)}
variant="secondary"
/>
{showAdvancedOptions && (
<form onSubmit={onSubmit}>
@@ -20,7 +20,7 @@
&__actions {
display: flex;
gap: $pad-medium;
gap: $gap-action-elements;
flex: 1;
justify-content: flex-end;
}
@@ -51,7 +51,6 @@ const AdvancedOptionsForm = ({
hideText="Advanced options"
caretPosition="after"
onClick={() => setShowAdvancedOptions(!showAdvancedOptions)}
variant="secondary"
/>
{showAdvancedOptions && (
<form onSubmit={handleSubmit}>
@@ -26,7 +26,7 @@
&__actions {
display: flex;
gap: $pad-medium;
gap: $gap-action-elements;
flex: 1;
justify-content: flex-end;
}
@@ -41,7 +41,7 @@
&__action-buttons {
display: flex;
flex-direction: row-reverse;
gap: $pad-medium;
gap: $gap-action-elements;
}
fieldset {
@@ -83,7 +83,8 @@ const FleetAppDetailsModal = ({
}
value={
<>
{slug} <CopyButton copyText={slug} variant="subdued" />
{slug}
<CopyButton copyText={slug} variant="compact" />
</>
}
/>
@@ -236,7 +236,7 @@ const SelfServiceCategoriesPage = ({
{canManage && (
<div className={`${baseClass}__row-actions`}>
<Button
variant="subdued"
variant="secondary"
onClick={() => setCategoryToEdit(listItem)}
ariaLabel={`Edit ${listItem.name}`}
title="Edit"
@@ -244,7 +244,7 @@ const SelfServiceCategoriesPage = ({
<Icon name="pencil" />
</Button>
<Button
variant="subdued"
variant="secondary"
onClick={() => setCategoryToDelete(listItem)}
ariaLabel={`Delete ${listItem.name}`}
title="Delete"
+1 -1
View File
@@ -29,7 +29,7 @@
&__action-buttons {
display: flex;
align-items: center;
gap: $pad-small;
gap: $gap-action-elements;
}
&__text {
@@ -285,7 +285,6 @@ const PackageAdvancedOptions = ({
hideText="Advanced options"
caretPosition="after"
onClick={() => setShowAdvancedOptions(!showAdvancedOptions)}
variant="secondary"
disabled={!selectedPackage || requiresAdvancedOptions}
disabledTooltipContent={
requiresAdvancedOptions ? (
@@ -64,6 +64,6 @@
&__action-buttons {
display: flex;
flex-direction: row-reverse;
gap: $pad-large;
gap: $gap-action-elements;
}
}
@@ -105,6 +105,6 @@
&__action-buttons {
display: flex;
flex-direction: row-reverse;
gap: $pad-medium;
gap: $gap-action-elements;
}
}
@@ -114,6 +114,6 @@
&__action-buttons {
display: flex;
flex-direction: row-reverse;
gap: $pad-medium;
gap: $gap-action-elements;
}
}
@@ -308,7 +308,8 @@ const OktaConditionalAccessModal = ({
isLoading={isDownloadingCert}
disabled={isDownloadingCert}
>
Download certificate <Icon name="download" />
<span>Download certificate</span>
<Icon name="download" />
</Button>
</div>
@@ -59,7 +59,7 @@
&__button-wrap {
display: flex;
justify-content: flex-end;
gap: $pad-small;
gap: $gap-action-elements;
.renew-cert-modal__request-button {
margin: 0;
@@ -428,7 +428,6 @@ const TeamDetailsWrapper = ({
type: "secondary",
label: "Manage enroll secrets",
buttonVariant: "secondary",
iconName: "eye",
onClick: toggleManageEnrollSecretsModal,
gitOpsModeCompatible: true,
},
@@ -436,7 +435,6 @@ const TeamDetailsWrapper = ({
type: "secondary",
label: "Rename fleet",
buttonVariant: "secondary",
iconName: "pencil",
onClick: toggleRenameFleetModal,
gitOpsModeCompatible: true,
},
@@ -444,7 +442,6 @@ const TeamDetailsWrapper = ({
type: "secondary",
label: "Delete fleet",
buttonVariant: "secondary",
iconName: "trash",
hideAction: !isGlobalAdmin,
onClick: toggleDeleteFleetModal,
gitOpsModeCompatible: true,
@@ -70,7 +70,7 @@ export const DownloadABMKey = ({
onClick={handleDownload}
>
<label htmlFor="download-key">
<Icon name="download" size="medium" />
<Icon name="download" />
<span>Download public key</span>
</label>
</Button>
@@ -66,7 +66,7 @@ export const DownloadCSR = ({
onClick={handleDownload}
>
<label htmlFor="request-csr">
<Icon name="download" size="medium" />
<Icon name="download" />
<span>Download CSR</span>
</label>
</Button>
@@ -8,7 +8,7 @@
&__button-wrap {
display: flex;
align-items: center;
gap: $pad-medium;
gap: $gap-action-elements;
}
.ace-fleet {
@@ -104,7 +104,7 @@
.manage-hosts__table-actions {
display: flex;
align-items: center;
gap: $pad-medium; // grouping secondary buttons
gap: $gap-table-elements; // grouping secondary buttons
}
.manage-hosts__filter-dropdowns {
@@ -17,7 +17,7 @@
position: relative;
display: flex;
align-items: center;
gap: $pad-medium;
gap: $pad-small;
margin-bottom: $pad-medium;
// Scoped to a direct child so this doesn't also catch the plus icon
@@ -101,7 +101,6 @@ const SettingUpYourDevice = ({
hideText="Details"
caretPosition="after"
onClick={() => setShowError(!showError)}
variant="secondary"
/>
{showError && (
<Textarea variant="code">{failedSoftware.error}</Textarea>
@@ -73,6 +73,6 @@
display: flex;
flex-direction: row;
align-items: center;
gap: $pad-medium;
gap: $gap-action-elements;
}
}
@@ -60,10 +60,7 @@
&__action-button-container {
display: flex;
align-items: flex-start;
}
&__advanced-button {
margin-right: $pad-medium;
gap: $gap-action-elements;
}
&__sandbox-info {
@@ -195,7 +195,6 @@ const CalendarEventsModal = forwardRef<
showText="Example payload"
caretPosition="after"
onClick={() => setShowExamplePayload(!showExamplePayload)}
variant="secondary"
/>
{showExamplePayload && renderExamplePayload()}
</>
@@ -293,7 +293,6 @@ const OtherWorkflowsModal = forwardRef<
showText="Show example ticket"
caretPosition="after"
onClick={() => setShowExampleTicket(!showExampleTicket)}
variant="secondary"
/>
{showExampleTicket && (
<ExampleTicket
@@ -377,7 +376,6 @@ const OtherWorkflowsModal = forwardRef<
showText="Example payload"
caretPosition="after"
onClick={() => setShowExamplePayload(!showExamplePayload)}
variant="secondary"
/>
{showExamplePayload && <ExamplePayload />}
</>
@@ -32,7 +32,7 @@
&__filter-dropdowns {
display: flex;
align-items: center;
gap: $pad-medium;
gap: $gap-table-elements;
}
&__platform-dropdown {
@@ -42,7 +42,7 @@
&__action-button-container {
display: flex;
gap: $pad-small;
gap: $gap-action-elements;
}
.queries-table {
@@ -20,7 +20,7 @@
display: flex;
justify-content: flex-end;
min-width: max-content;
gap: $pad-medium;
gap: $gap-action-elements;
}
&__query-name {
@@ -538,7 +538,6 @@ const EditQueryForm = ({
hideText="Hide SQL"
showText="Show SQL"
onClick={() => setShowQueryEditor(!showQueryEditor)}
variant="secondary"
/>
)}
{showQueryEditor && (
@@ -782,7 +781,6 @@ const EditQueryForm = ({
showText="Advanced options"
caretPosition="after"
onClick={toggleAdvancedOptions}
variant="secondary"
/>
{showAdvancedOptions && (
<>
@@ -339,7 +339,6 @@ const SaveNewQueryModal = ({
showText="Advanced options"
caretPosition="after"
onClick={toggleAdvancedOptions}
variant="secondary"
/>
{showAdvancedOptions && (
<>
@@ -52,13 +52,9 @@
margin-top: 30px;
display: flex;
align-items: center;
button:not(:first-of-type) {
margin-left: 16px;
}
gap: $gap-action-elements;
}
&__targets-total-count {
margin-left: 16px;
font-size: $x-small;
display: flex;
align-items: center;
+2 -2
View File
@@ -138,12 +138,12 @@ form,
.button-wrap {
margin: 0;
display: flex;
gap: $pad-medium;
gap: $gap-action-elements;
&--center {
margin: 0;
display: flex;
gap: $pad-medium;
gap: $gap-action-elements;
justify-content: center;
}
}
+2 -1
View File
@@ -19,7 +19,8 @@ $gap-page-component-inner-responsiveness: $pad-smedium;
$gap-form: $pad-large;
$gap-form-component: $pad-small;
$gap-data-sets: $pad-medium;
$gap-table-elements: $pad-medium;
$gap-table-elements: $pad-small;
$gap-action-elements: $pad-small;
$gap-modal-component: $pad-large;
$gap-icon-text: $pad-small;
$table-cell-padding: $pad-large;