Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix floating ui #880

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
5 changes: 5 additions & 0 deletions .changeset/cool-balloons-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@saleor/macaw-ui": patch
---

Floating ui now working corectly with react 18
13 changes: 12 additions & 1 deletion src/components/Combobox/Common/useCombobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,16 @@ export const useCombobox = <T extends Option, V extends string | Option>({
highlightedIndex,
onHighlightedIndexChange,
isItemDisabled: (item) => item?.disabled ?? false,
onStateChange: ({ inputValue: newInputValue, type }) => {
onStateChange: ({ inputValue: newInputValue, type, selectedItem }) => {
// eslint-disable-next-line no-console
console.log("Debug useCombobox state change type", type);
// eslint-disable-next-line no-console
console.log("Debug useCombobox state change input value", inputValue);
// eslint-disable-next-line no-console
console.log(
"Debug useCombobox state change new selected item",
selectedItem
);
switch (type) {
case useDownshiftCombobox.stateChangeTypes.InputChange:
onInputValueChange?.(newInputValue ?? "");
Expand All @@ -80,6 +89,8 @@ export const useCombobox = <T extends Option, V extends string | Option>({
}
},
onSelectedItemChange: ({ selectedItem }) => {
// eslint-disable-next-line no-console
console.log("onSelectedItemChange", selectedItem);
if (selectedItem) {
const selectedValue = isValuePassedAsString
? selectedItem.value
Expand Down
11 changes: 6 additions & 5 deletions src/components/Combobox/Dynamic/DynamicCombobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ const DynamicComboboxInner = <T extends Option>(
onBlur,
});

const { refs, floatingStyles } = useFloating();
const { refs, floatingStyles } = useFloating<HTMLLabelElement>({
shouldUpdate: isOpen,
});

const scrollRef = useInfinityScroll(onScrollEnd);

Expand All @@ -120,7 +122,7 @@ const DynamicComboboxInner = <T extends Option>(
<Box display="flex" flexDirection="column">
<ComboboxWrapper
id={id}
ref={refs.setReference}
ref={refs.reference}
typed={typed}
active={active}
disabled={disabled}
Expand Down Expand Up @@ -149,7 +151,7 @@ const DynamicComboboxInner = <T extends Option>(
{endAdornment && typed && <Box>{endAdornment(value)}</Box>}
</Box>
</ComboboxWrapper>
<Portal asChild ref={refs.setFloating} style={floatingStyles}>
<Portal asChild style={floatingStyles}>
<Box
position="relative"
display={getListDisplayMode({
Expand All @@ -165,8 +167,7 @@ const DynamicComboboxInner = <T extends Option>(
<List
as="ul"
className={listStyle}
// suppress error because of rendering list in portal
{...getMenuProps({}, { suppressRefError: true })}
{...getMenuProps({ ref: refs.floating })}
>
{isOpen &&
itemsToSelect?.map((item, index) => (
Expand Down
11 changes: 6 additions & 5 deletions src/components/Combobox/Static/Combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ const ComboboxInner = <T extends Option, V extends Option | string>(
onBlur,
});

const { refs, floatingStyles } = useFloating();
const { refs, floatingStyles } = useFloating<HTMLLabelElement>({
shouldUpdate: isOpen,
});

const inputProps = getInputProps({
id,
Expand All @@ -109,7 +111,7 @@ const ComboboxInner = <T extends Option, V extends Option | string>(
<Box display="flex" flexDirection="column">
<ComboboxWrapper
id={id}
ref={refs.setReference}
ref={refs.reference}
typed={typed}
active={active}
disabled={disabled}
Expand Down Expand Up @@ -142,7 +144,7 @@ const ComboboxInner = <T extends Option, V extends Option | string>(
</Box>
</ComboboxWrapper>

<Portal asChild ref={refs.setFloating} style={floatingStyles}>
<Portal asChild style={floatingStyles}>
<Box
position="relative"
display={getListDisplayMode({
Expand All @@ -157,8 +159,7 @@ const ComboboxInner = <T extends Option, V extends Option | string>(
<List
as="ul"
className={listStyle}
// suppress error because of rendering list in portal
{...getMenuProps({}, { suppressRefError: true })}
{...getMenuProps({ ref: refs.floating })}
>
{isOpen &&
itemsToSelect?.map((item, index) => (
Expand Down
2 changes: 1 addition & 1 deletion src/components/List/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type ListProps = PropsWithBox<{
className?: string;
}>;

export const List = forwardRef<HTMLUListElement | HTMLOListElement, ListProps>(
export const List = forwardRef<HTMLElement, ListProps>(
({ children, as = "ul", className, ...rest }, ref) => {
return (
<Box
Expand Down
3 changes: 3 additions & 0 deletions src/components/Multiselect/Common/useMultiselect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ export const useMultiselect = <T extends Option, V extends Option | string>({
useMultipleSelection({
selectedItems,
onStateChange({ selectedItems: newSelectedItems, type }) {
// eslint-disable-next-line no-console
console.log("Debug useCombobox state change", type, newSelectedItems);

switch (type) {
case useMultipleSelection.stateChangeTypes
.SelectedItemKeyDownBackspace:
Expand Down
11 changes: 6 additions & 5 deletions src/components/Multiselect/Dynamic/DynamicMultiselect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ const DynamicMultiselectInner = <T extends Option>(
onBlur,
});

const { refs, floatingStyles } = useFloating();
const { refs, floatingStyles } = useFloating<HTMLLabelElement>({
shouldUpdate: isOpen,
});

const scrollRef = useInfinityScroll(onScrollEnd);

Expand All @@ -127,7 +129,7 @@ const DynamicMultiselectInner = <T extends Option>(
return (
<Box display="flex" flexDirection="column">
<MultiselectWrapper
ref={refs.setReference}
ref={refs.reference}
id={id}
typed={typed}
active={active}
Expand Down Expand Up @@ -194,7 +196,7 @@ const DynamicMultiselectInner = <T extends Option>(
/>
</MultiselectWrapper>

<Portal asChild ref={refs.setFloating} style={floatingStyles}>
<Portal asChild style={floatingStyles}>
<Box
position="relative"
display={getListDisplayMode({
Expand All @@ -209,8 +211,7 @@ const DynamicMultiselectInner = <T extends Option>(
<List
as="ul"
className={listStyle}
// suppress error because of rendering list in portal
{...getMenuProps({}, { suppressRefError: true })}
{...getMenuProps({ ref: refs.floating })}
>
{isOpen &&
itemsToSelect?.map((item, index) => (
Expand Down
11 changes: 6 additions & 5 deletions src/components/Multiselect/Static/Multiselect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ const MultiselectInner = <T extends Option, V extends Option | string>(
onBlur,
});

const { refs, floatingStyles } = useFloating();
const { refs, floatingStyles } = useFloating<HTMLLabelElement>({
shouldUpdate: isOpen,
});

const inputProps = getInputProps({
id,
Expand All @@ -116,8 +118,8 @@ const MultiselectInner = <T extends Option, V extends Option | string>(
return (
<Box display="flex" flexDirection="column">
<MultiselectWrapper
ref={refs.setReference}
id={id}
ref={refs.reference}
typed={typed}
active={active}
disabled={disabled}
Expand Down Expand Up @@ -183,7 +185,7 @@ const MultiselectInner = <T extends Option, V extends Option | string>(
/>
</MultiselectWrapper>

<Portal asChild ref={refs.setFloating} style={floatingStyles}>
<Portal asChild style={floatingStyles}>
<Box
position="relative"
display={isOpen ? "block" : "none"}
Expand All @@ -192,8 +194,7 @@ const MultiselectInner = <T extends Option, V extends Option | string>(
<List
as="ul"
className={listStyle}
// suppress error because of rendering list in portal
{...getMenuProps({}, { suppressRefError: true })}
{...getMenuProps({ ref: refs.floating })}
>
{isOpen &&
itemsToSelect?.map((item, index) => (
Expand Down
14 changes: 8 additions & 6 deletions src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ const SelectInner = <T extends Option, V extends Option | string>(
onBlur,
});

const { refs, floatingStyles } = useFloating();
const { refs, floatingStyles } = useFloating<HTMLLabelElement>({
shouldUpdate: isOpen,
});

const labelColor = useMemo((): TextProps["color"] => {
if (error) {
Expand All @@ -131,7 +133,6 @@ const SelectInner = <T extends Option, V extends Option | string>(
return (
<Box display="flex" flexDirection="column">
<SelectWrapper
ref={refs.setReference}
id={id}
typed={typed}
active={active}
Expand All @@ -141,7 +142,9 @@ const SelectInner = <T extends Option, V extends Option | string>(
error={error}
className={className}
getLabelProps={getLabelProps}
getToggleButtonProps={getToggleButtonProps}
getToggleButtonProps={() =>
getToggleButtonProps({ ref: refs.reference })
}
>
<Box height={getBoxHeight(size)} {...props} ref={ref} display="flex">
{startAdornment && typed && startAdornment(value)}
Expand All @@ -159,7 +162,7 @@ const SelectInner = <T extends Option, V extends Option | string>(
{endAdornment && typed && endAdornment(value)}
</Box>
</SelectWrapper>
<Portal asChild ref={refs.setFloating} style={floatingStyles}>
<Portal asChild style={floatingStyles}>
<Box
position="relative"
display={getListDisplayMode({
Expand All @@ -173,8 +176,7 @@ const SelectInner = <T extends Option, V extends Option | string>(
<List
as="ul"
className={listStyle}
// suppress error because of rendering list in portal
{...getMenuProps({}, { suppressRefError: true })}
{...getMenuProps({ ref: refs.floating })}
>
{isOpen &&
options?.map((item, index) => (
Expand Down
113 changes: 52 additions & 61 deletions src/components/Select/SelectWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Do not expose this file, it's for internal purposes only.
*/
import { UseSelectPropGetters } from "downshift";
import { ReactNode, forwardRef } from "react";
import { ReactNode } from "react";

import { classNames } from "~/utils";

Expand All @@ -23,69 +23,60 @@ type SelectWrapperProps = LabelVariants & {
getLabelProps: UseSelectPropGetters<Option>["getLabelProps"];
};

export const SelectWrapper = forwardRef<HTMLLabelElement, SelectWrapperProps>(
(
{
id,
label,
className,
error,
children,
getToggleButtonProps,
getLabelProps,
typed,
active,
disabled,
size,
},
ref
) => {
return (
<Box ref={ref}>
export const SelectWrapper = ({
id,
label,
className,
error,
children,
getToggleButtonProps,
getLabelProps,
typed,
active,
disabled,
size,
}: SelectWrapperProps) => {
return (
<Box
as="label"
className={classNames(
labelRecipe({ typed, active, disabled, size, error }),
className
)}
alignItems="center"
justifyContent="space-between"
disabled={disabled}
flexWrap="nowrap"
gap={3}
{...getToggleButtonProps()}
data-macaw-ui-component="Select"
cursor={disabled ? "not-allowed" : "pointer"}
>
<Box
display="flex"
flexDirection="column"
// Take full width minus the arrow icon width
__width="calc(100% - 30px)"
>
<Box
as="label"
className={classNames(
labelRecipe({ typed, active, disabled, size, error }),
className
)}
alignItems="center"
justifyContent="space-between"
disabled={disabled}
flexWrap="nowrap"
gap={3}
{...getToggleButtonProps()}
data-macaw-ui-component="Select"
cursor={disabled ? "not-allowed" : "pointer"}
as="span"
className={classNames(spanRecipe({ typed, size, disabled, error }))}
{...getLabelProps({ htmlFor: id })}
>
<Box
display="flex"
flexDirection="column"
// Take full width minus the arrow icon width
__width="calc(100% - 30px)"
>
<Box
as="span"
className={classNames(
spanRecipe({ typed, size, disabled, error })
)}
{...getLabelProps({ htmlFor: id })}
>
{label}
</Box>
{children}
</Box>

<ArrowDownIcon
className={classNames(
toggleIconStyle,
sprinkles({ cursor: "pointer" })
)}
size={size}
/>
{label}
</Box>
{children}
</Box>
);
}
);

<ArrowDownIcon
className={classNames(
toggleIconStyle,
sprinkles({ cursor: "pointer" })
)}
size={size}
/>
</Box>
);
};

SelectWrapper.displayName = "SelectWrapper";
4 changes: 4 additions & 0 deletions src/components/Select/useSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export const useSelect = <T extends Option, V extends string | Option>({
onHighlightedIndexChange(change);
},
itemToString: (item) => item?.value ?? "",
onStateChange({ selectedItem, type }) {
// eslint-disable-next-line no-console
console.log("Debug useCombobox state change", type, selectedItem);
},
onSelectedItemChange: ({ selectedItem }) => {
if (selectedItem) {
const selectedValue = isValuePassedAsString
Expand Down
Loading
Loading