GitOps mode tooltip fixes (#48280)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
  **Related issue:** Resolves #44325 (follow-up to #47861 and #48009)

  ## Summary

Follow-up to #47861 and #48009 (both merged) for #44325. Those left
several GitOps-mode "Manage in YAML" tooltips still misaligned. This
makes the wrapper hug its content so the tooltip centers on the disabled
control instead of drifting to the full form width.

  # Checklist for submitter

  ## Testing

  - [x] QA'd all new/changed functionality manually

<img width="1280" height="860" alt="1_bootstrap_advanced"
src="https://github.com/user-attachments/assets/403cabb4-3d24-4ece-91f5-4887efd0da05"
/>
<img width="1280" height="860" alt="2_install_software"
src="https://github.com/user-attachments/assets/2f9b2130-0fd6-4744-9603-1a31aebd773e"
/>
<img width="1280" height="860" alt="3_fleet_action_rename"
src="https://github.com/user-attachments/assets/180f3e8d-1dee-404c-b13d-14124bc3509b"
/>
<img width="1280" height="860" alt="4_fleet_action_enroll"
src="https://github.com/user-attachments/assets/9378b6fb-5b1e-45e0-80e5-61d4996b49e0"
/>
<img width="1280" height="860" alt="5_fleet_checkbox"
src="https://github.com/user-attachments/assets/dcec8992-5407-452a-8b4c-5d4e8dc27d10"
/>



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved tooltip positioning and width behavior in setup forms so
tooltips align more consistently with the visible control.
* Input and dropdown fields now keep their full-width behavior, while
other controls are centered more naturally.
* Updated the macOS and Windows software requirement options to show
tooltips beside the control for better readability.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Carlo
2026-06-25 14:56:18 -04:00
committed by GitHub
parent 6a129ec7fc
commit 6ad9497409
4 changed files with 15 additions and 14 deletions
@@ -16,8 +16,9 @@ interface IGitOpsModeTooltipWrapper {
// When specified, the wrapper checks the exception for this entity type.
// If the entity is excepted, children remain enabled even in GitOps mode.
entityType?: keyof IGitOpsExceptions;
/** Set to true when wrapping an input field or other block-level form element
* so the tooltip wrapper stretches to full width. */
/** Set to true when wrapping an input/dropdown or a group of them that must stretch to the
* full form width. By default the wrapper hugs its content so the tooltip centers on the
* control; inputs opt back into full width. */
isInputField?: boolean;
}
@@ -42,7 +43,6 @@ const GitOpsModeTooltipWrapper = ({
const wrapperRef = useRef<HTMLSpanElement>(null);
const [hasSingleFieldRow, setHasSingleFieldRow] = useState(false);
const [wrapsField, setWrapsField] = useState(true);
// Prefix makes this a valid CSS id selector (lodash uniqueId returns a bare number).
const wrapperId = useMemo(() => uniqueId(`${baseClass}-`), []);
@@ -57,10 +57,6 @@ const GitOpsModeTooltipWrapper = ({
FIRST_ROW_PARTS.join(", ")
);
setHasSingleFieldRow(!!root?.matches(".form-field") && rows?.length === 1);
// Field content (a single field or a group of them) keeps full width so the disabled
// row stays the hover target; only non-field content (buttons, icon rows) hugs its
// content so the tooltip centers on the button rather than the full form row.
setWrapsField(!!wrapperRef.current?.querySelector(".form-field"));
}, []);
if (!gitOpsModeEnabled) {
@@ -73,9 +69,11 @@ const GitOpsModeTooltipWrapper = ({
</div>
);
// Hug the wrapped content (buttons, checkboxes, groups) so the tooltip centers on the visible
// control instead of the full-width form row. Inputs/dropdowns opt back into full width.
const wrapperClass = classnames(baseClass, {
[`${baseClass}--inputfield`]: isInputField,
[`${baseClass}--hug`]: !wrapsField && !isInputField,
[`${baseClass}--hug`]: !isInputField,
});
// Anchor to the field's first row so the arrow points at the label regardless of input,
@@ -21,10 +21,12 @@
width: 100%;
}
// Non-field content (buttons, icon rows) hugs its content so the tooltip centers on the
// button. Without this, the global `form > * { width: 100% }` rule (_global.scss) stretches
// the span to the full form width and the arrow drifts to the form center. Field wrappers
// deliberately keep full width so the disabled row stays the hover target.
// Hug the wrapped content so the tooltip arrow centers on the visible control (a button,
// checkbox row, or group) rather than drifting to the center of the full form row. Without
// this, the global `form > * { width: 100% }` rule (_global.scss) — or a checkbox's own
// full-width label row stretches the anchor wider than the control. Inputs/dropdowns opt
// back into full width via `--inputfield`. (In GitOps mode the control is disabled, so the
// narrower hover area is moot.)
&--hug {
width: fit-content;
}
@@ -280,7 +280,7 @@ const InstallSoftwareForm = ({
<div className={`${baseClass}__macos_options`}>
<GitOpsModeTooltipWrapper
tipOffset={6}
position="bottom-start"
position="left"
entityType="software"
renderChildren={(disableChildren) => (
<Checkbox
@@ -305,7 +305,7 @@ const InstallSoftwareForm = ({
<div className={`${baseClass}__windows_options`}>
<GitOpsModeTooltipWrapper
tipOffset={6}
position="bottom-start"
position="left"
entityType="software"
renderChildren={(disableChildren) => (
<Checkbox
@@ -76,6 +76,7 @@ const LocalAccountSection = ({
<GitOpsModeTooltipWrapper
position="left"
tipOffset={8}
isInputField
renderChildren={(gitopsEnabled) => {
return (
<div className={`${baseClass}__field-group`}>