Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions packages/components/src/Autocomplete/Autocomplete.rebuilt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ function AutocompleteRebuiltInternal<
duration: { open: tokens["timing-base"], close: tokens["timing-base"] },
});

const [menuWidth, setMenuWidth] = React.useState<number | undefined>(
undefined,
);
const [positionRefEl, setPositionRefEl] = React.useState<Element | null>(
null,
);
Expand Down Expand Up @@ -197,7 +194,6 @@ function AutocompleteRebuiltInternal<
);

if (multiContainer) {
setMenuWidth(multiContainer.clientWidth);
setPositionRefEl(multiContainer);
}
},
Expand All @@ -209,14 +205,14 @@ function AutocompleteRebuiltInternal<
setReferenceElement(node);

if (!props.multiple) {
// Workaround to get the width of the visual InputText element, which is not the same as
// the literal input reference element.
// Workaround to get the visual InputText element, which is not the same
// as the literal input reference element when props like suffix/prefix
// are present. Used to set the position reference for the floating menu.
const visualInputTextElement = node?.closest(
"[data-testid='Form-Field-Wrapper']",
);

if (visualInputTextElement) {
setMenuWidth(visualInputTextElement.clientWidth);
setPositionRefEl(visualInputTextElement);
}
}
Expand Down Expand Up @@ -252,7 +248,6 @@ function AutocompleteRebuiltInternal<
className={menuClassName}
floatingStyles={floatingStyles}
transitionStyles={transitionStyles}
menuWidth={menuWidth}
menuStyle={props.UNSAFE_styles?.menu}
renderable={renderable}
persistentsHeaders={persistentsHeaders}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ interface FloatingMenuProps<Value extends OptionLike> {
readonly className: string;
readonly floatingStyles: React.CSSProperties;
readonly transitionStyles: React.CSSProperties;
readonly menuWidth?: number;
readonly menuStyle?: React.CSSProperties;

readonly renderable: Array<RenderItem<Value>>;
Expand Down Expand Up @@ -89,7 +88,6 @@ export function FloatingMenu<Value extends OptionLike>({
className,
floatingStyles,
transitionStyles,
menuWidth,
menuStyle,
renderable,
persistentsHeaders,
Expand Down Expand Up @@ -139,7 +137,6 @@ export function FloatingMenu<Value extends OptionLike>({
...floatingStyles,
...transitionStyles,
...menuStyle,
...(menuWidth ? { width: menuWidth, maxWidth: menuWidth } : {}),
},
})}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ export interface UseAutocompleteListNavProps {
outsidePressExcludeSelector?: string;
}

function useStableSetReference(
refs: UseFloatingReturn["refs"],
): (el: HTMLElement | null) => void {
const latestRefs = useRef(refs);
latestRefs.current = refs;

return useCallback(
(el: HTMLElement | null) => latestRefs.current.setReference(el),
[],
);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my first thought is if we could use useCallbackRef instead.

something like const setReferenceElement = useCallbackRef(() => refs.setReference);

I'll have to double check this is equivalent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useCallbackRef(() => refs.setReference) isn’t equivalent because it returns the function instead of invoking it with the element. I’d need useCallbackRef((el) => refs.setReference(el)), but for a ref callback useStableSetReference is safer since it keeps refs current during render rather than after commit (useEffect).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough, I'm happy to leave it as is then.

export function useAutocompleteListNav({
navigableCount,
shouldResetActiveIndexOnClose,
Expand Down Expand Up @@ -84,12 +96,13 @@ export function useAutocompleteListNav({
offset(MENU_OFFSET),
flip({ fallbackPlacements: ["top"] }),
size({
apply({ availableHeight, elements }) {
apply({ availableHeight, rects, elements }) {
const maxHeight = calculateMaxHeight(availableHeight, {
maxHeight: AUTOCOMPLETE_MAX_HEIGHT,
});
Object.assign(elements.floating.style, {
maxHeight: `${maxHeight}px`,
width: `${rects.reference.width}px`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clever! I forgot rects is available here. I like the colocation of dimension related setting code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did notice we used to have a maxWidth too. I can't recall why that was added... maybe it's not necessary with this setup.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxWidth came from the old menuWidth workaround, and since we now set width from rects.reference.width in the floating size middleware (with the wrapper as the position reference), it seems redundant unless we intentionally want a different cap behavior.

});
},
}),
Expand Down Expand Up @@ -154,10 +167,7 @@ export function useAutocompleteListNav({
});
}, [navigableCount, setActiveIndex, listRef]);

const setReferenceElement = useCallback(
(el: HTMLElement | null) => refs.setReference(el),
[refs],
);
const setReferenceElement = useStableSetReference(refs);

return {
refs,
Expand Down
6 changes: 4 additions & 2 deletions packages/components/src/InputText/InputText.rebuilt.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { InputHTMLAttributes, TextareaHTMLAttributes } from "react";
import React, { forwardRef, useId } from "react";
import React, { forwardRef, useId, useMemo } from "react";
import type { InputTextRebuiltProps } from "./InputText.types";
import { useTextAreaResize } from "./useTextAreaResize";
import { useInputTextActions } from "./useInputTextActions";
Expand Down Expand Up @@ -64,6 +64,8 @@ export const InputTextSPAR = forwardRef(function InputTextInternal(
const isInvalid = Boolean(props.error || props.invalid);
const dataAttrs = filterDataAttributes(props);

const mergedRef = useMemo(() => mergeRefs([inputRef, inputTextRef]), []);

// Shared props for both TextArea and TextInput
const commonInputProps = {
id,
Expand Down Expand Up @@ -98,7 +100,7 @@ export const InputTextSPAR = forwardRef(function InputTextInternal(
onPointerDown: handlePointerDown,
onPointerUp: handlePointerUp,
onClick: handleClick,
ref: mergeRefs([inputRef, inputTextRef]),
ref: mergedRef,
...dataAttrs,
};

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading