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: collection based components ref #4207

Merged
merged 1 commit into from
Dec 1, 2024
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
13 changes: 13 additions & 0 deletions .changeset/dirty-tigers-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@nextui-org/autocomplete": patch
"@nextui-org/date-picker": patch
"@nextui-org/date-input": patch
"@nextui-org/calendar": patch
"@nextui-org/dropdown": patch
"@nextui-org/listbox": patch
"@nextui-org/select": patch
"@nextui-org/menu": patch
"@nextui-org/tabs": patch
---

Fix the "forwardRef render functions accept exactly two parameters: props and ref. Did you forget to use the ref parameter?" on next.js by changing the way we manage collection base components refs
20 changes: 9 additions & 11 deletions packages/components/autocomplete/src/autocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@ import {ChevronDownIcon, CloseIcon} from "@nextui-org/shared-icons";
import {Listbox} from "@nextui-org/listbox";
import {Button} from "@nextui-org/button";
import {Input} from "@nextui-org/input";
import {ForwardedRef, ReactElement, Ref} from "react";
import {ForwardedRef, ReactElement} from "react";
import {AnimatePresence} from "framer-motion";

import {UseAutocompleteProps, useAutocomplete} from "./use-autocomplete";

interface Props<T> extends UseAutocompleteProps<T> {}

function Autocomplete<T extends object>(props: Props<T>, ref: ForwardedRef<HTMLInputElement>) {
export type AutocompleteProps<T extends object = object> = Props<T>;

const Autocomplete = forwardRef(function Autocomplete<T extends object>(
props: AutocompleteProps<T>,
ref: ForwardedRef<HTMLInputElement>,
) {
const {
Component,
isOpen,
Expand Down Expand Up @@ -57,13 +62,6 @@ function Autocomplete<T extends object>(props: Props<T>, ref: ForwardedRef<HTMLI
{disableAnimation ? popoverContent : <AnimatePresence>{popoverContent}</AnimatePresence>}
</Component>
);
}

export type AutocompleteProps<T extends object = object> = Props<T> & {ref?: Ref<HTMLElement>};

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(Autocomplete) as <T extends object>(
props: AutocompleteProps<T>,
) => ReactElement;
}) as <T extends object>(props: AutocompleteProps<T>) => ReactElement;

Autocomplete.displayName = "NextUI.Autocomplete";
export default Autocomplete;
20 changes: 9 additions & 11 deletions packages/components/calendar/src/calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {DateValue} from "@internationalized/date";
import type {ForwardedRef, ReactElement, Ref} from "react";
import type {ForwardedRef, ReactElement} from "react";

import {forwardRef} from "@nextui-org/system";

Expand All @@ -9,21 +9,19 @@ import {CalendarBase} from "./calendar-base";

interface Props<T extends DateValue> extends Omit<UseCalendarProps<T>, "isHeaderWrapperExpanded"> {}

function Calendar<T extends DateValue>(props: Props<T>, ref: ForwardedRef<HTMLDivElement>) {
export type CalendarProps<T extends DateValue = DateValue> = Props<T>;

const Calendar = forwardRef(function Calendar<T extends DateValue>(
props: CalendarProps<T>,
ref: ForwardedRef<HTMLDivElement>,
) {
const {context, getBaseCalendarProps} = useCalendar<T>({...props, ref});

return (
<CalendarProvider value={context}>
<CalendarBase {...getBaseCalendarProps()} />
</CalendarProvider>
);
}

Calendar.displayName = "NextUI.Calendar";
}) as <T extends DateValue>(props: CalendarProps<T>) => ReactElement;

export type CalendarProps<T extends DateValue = DateValue> = Props<T> & {ref?: Ref<HTMLElement>};

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(Calendar) as <T extends DateValue>(
props: CalendarProps<T>,
) => ReactElement;
export default Calendar;
22 changes: 9 additions & 13 deletions packages/components/calendar/src/range-calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {DateValue} from "@internationalized/date";
import type {ForwardedRef, ReactElement, Ref} from "react";
import type {ForwardedRef, ReactElement} from "react";

import {forwardRef} from "@nextui-org/system";

Expand All @@ -13,23 +13,19 @@ interface Props<T extends DateValue>
"isHeaderExpanded" | "onHeaderExpandedChange" | "isHeaderWrapperExpanded"
> {}

function RangeCalendar<T extends DateValue>(props: Props<T>, ref: ForwardedRef<HTMLDivElement>) {
export type RangeCalendarProps<T extends DateValue = DateValue> = Props<T>;

const RangeCalendar = forwardRef(function RangeCalendar<T extends DateValue>(
props: RangeCalendarProps<T>,
ref: ForwardedRef<HTMLDivElement>,
) {
const {context, getBaseCalendarProps} = useRangeCalendar<T>({...props, ref});

return (
<CalendarProvider value={context}>
<CalendarBase {...getBaseCalendarProps()} />
</CalendarProvider>
);
}

RangeCalendar.displayName = "NextUI.RangeCalendar";
}) as <T extends DateValue>(props: RangeCalendarProps<T>) => ReactElement;

export type RangeCalendarProps<T extends DateValue = DateValue> = Props<T> & {
ref?: Ref<HTMLElement>;
};

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(RangeCalendar) as <T extends DateValue>(
props: RangeCalendarProps<T>,
) => ReactElement;
export default RangeCalendar;
25 changes: 10 additions & 15 deletions packages/components/date-input/src/date-input.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {DateValue} from "@internationalized/date";
import type {ForwardedRef, ReactElement, Ref} from "react";
import type {ForwardedRef, ReactElement} from "react";

import {forwardRef} from "@nextui-org/system";

Expand All @@ -9,12 +9,14 @@ import {DateInputField} from "./date-input-field";

export interface Props<T extends DateValue> extends UseDateInputProps<T> {}

function DateInput<T extends DateValue>(props: Props<T>, ref: ForwardedRef<HTMLDivElement>) {
export type DateInputProps<T extends DateValue = DateValue> = Props<T>;

const DateInput = forwardRef(function DateInput<T extends DateValue>(
props: DateInputProps<T>,
ref: ForwardedRef<HTMLDivElement>,
) {
const {state, slots, classNames, getBaseGroupProps, getInputProps, getFieldProps} =
useDateInput<T>({
...props,
ref,
});
useDateInput<T>({...props, ref});

return (
<DateInputGroup {...getBaseGroupProps()}>
Expand All @@ -27,13 +29,6 @@ function DateInput<T extends DateValue>(props: Props<T>, ref: ForwardedRef<HTMLD
/>
</DateInputGroup>
);
}

DateInput.displayName = "NextUI.DateInput";
}) as <T extends DateValue>(props: DateInputProps<T>) => ReactElement;

export type DateInputProps<T extends DateValue = DateValue> = Props<T> & {ref?: Ref<HTMLElement>};

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(DateInput) as <T extends DateValue>(
props: DateInputProps<T>,
) => ReactElement;
export default DateInput;
20 changes: 9 additions & 11 deletions packages/components/date-input/src/time-input.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {TimeValue} from "@react-types/datepicker";
import type {ForwardedRef, ReactElement, Ref} from "react";
import type {ForwardedRef, ReactElement} from "react";

import {forwardRef} from "@nextui-org/system";

Expand All @@ -9,7 +9,12 @@ import {DateInputGroup} from "./date-input-group";

export interface Props<T extends TimeValue> extends UseTimeInputProps<T> {}

function TimeInput<T extends TimeValue>(props: Props<T>, ref: ForwardedRef<HTMLDivElement>) {
export type TimeInputProps<T extends TimeValue = TimeValue> = Props<T>;

const TimeInput = forwardRef(function TimeInput<T extends TimeValue>(
props: TimeInputProps<T>,
ref: ForwardedRef<HTMLDivElement>,
) {
const {state, slots, classNames, getBaseGroupProps, getInputProps, getFieldProps} =
useTimeInput<T>({
...props,
Expand All @@ -27,13 +32,6 @@ function TimeInput<T extends TimeValue>(props: Props<T>, ref: ForwardedRef<HTMLD
/>
</DateInputGroup>
);
}

TimeInput.displayName = "NextUI.TimeInput";
}) as <T extends TimeValue>(props: TimeInputProps<T>) => ReactElement;

export type TimeInputProps<T extends TimeValue = TimeValue> = Props<T> & {ref?: Ref<HTMLElement>};

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(TimeInput) as <T extends TimeValue>(
props: TimeInputProps<T>,
) => ReactElement;
export default TimeInput;
20 changes: 9 additions & 11 deletions packages/components/date-picker/src/date-picker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {DateValue} from "@internationalized/date";

import {ForwardedRef, ReactElement, Ref, useMemo} from "react";
import {ForwardedRef, ReactElement, useMemo} from "react";
import {cloneElement, isValidElement} from "react";
import {forwardRef} from "@nextui-org/system";
import {Button} from "@nextui-org/button";
Expand All @@ -20,7 +20,12 @@ export interface Props<T extends DateValue> extends UseDatePickerProps<T> {
selectorButtonPlacement?: "start" | "end";
}

function DatePicker<T extends DateValue>(props: Props<T>, ref: ForwardedRef<HTMLDivElement>) {
export type DatePickerProps<T extends DateValue = DateValue> = Props<T>;

const DatePicker = forwardRef(function DatePicker<T extends DateValue>(
props: DatePickerProps<T>,
ref: ForwardedRef<HTMLInputElement>,
) {
const {selectorButtonPlacement = "end", ...otherProps} = props;

const {
Expand Down Expand Up @@ -98,13 +103,6 @@ function DatePicker<T extends DateValue>(props: Props<T>, ref: ForwardedRef<HTML
{disableAnimation ? popoverContent : <AnimatePresence>{popoverContent}</AnimatePresence>}
</>
);
}
}) as <T extends DateValue>(props: DatePickerProps<T>) => ReactElement;

DatePicker.displayName = "NextUI.DatePicker";

export type DatePickerProps<T extends DateValue = DateValue> = Props<T> & {ref?: Ref<HTMLElement>};

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(DatePicker) as <T extends DateValue>(
props: DatePickerProps<T>,
) => ReactElement;
export default DatePicker;
21 changes: 7 additions & 14 deletions packages/components/date-picker/src/date-range-picker-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {createCalendar} from "@internationalized/date";
import {forwardRef, useRef} from "react";
import {DateValue} from "@react-types/datepicker";
import {useDateField as useAriaDateField} from "@react-aria/datepicker";
import {ForwardedRef, ReactElement, Ref} from "react";
import {ForwardedRef, ReactElement} from "react";
import {useDateFieldState} from "@react-stately/datepicker";
import {DateInputSegment} from "@nextui-org/date-input";
import {filterDOMProps, useDOMRef} from "@nextui-org/react-utils";
Expand All @@ -29,8 +29,10 @@ export interface Props<T extends DateValue>
classNames?: SlotsToClasses<DateInputSlots>;
}

function DateRangePickerField<T extends DateValue>(
props: Props<T>,
export type DateRangePickerFieldProps<T extends DateValue = DateValue> = Props<T>;

const DateRangePickerField = forwardRef(function DateRangePickerField<T extends DateValue>(
props: DateRangePickerFieldProps<T>,
ref: ForwardedRef<HTMLDivElement>,
) {
const {as, slots, createCalendar: createCalendarProp, classNames, ...otherProps} = props;
Expand Down Expand Up @@ -76,15 +78,6 @@ function DateRangePickerField<T extends DateValue>(
<input {...inputProps} ref={inputRef} />
</Component>
);
}
}) as <T extends DateValue>(props: DateRangePickerFieldProps<T>) => ReactElement;

DateRangePickerField.displayName = "NextUI.DateRangePickerField";

export type DateRangePickerFieldProps<T extends DateValue = DateValue> = Props<T> & {
ref?: Ref<HTMLElement>;
};

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(DateRangePickerField) as <T extends DateValue>(
props: DateRangePickerFieldProps<T>,
) => ReactElement;
export default DateRangePickerField;
22 changes: 9 additions & 13 deletions packages/components/date-picker/src/date-range-picker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {DateValue} from "@internationalized/date";

import {ForwardedRef, ReactElement, Ref, useMemo} from "react";
import {ForwardedRef, ReactElement, useMemo} from "react";
import {cloneElement, isValidElement} from "react";
import {forwardRef} from "@nextui-org/system";
import {Button} from "@nextui-org/button";
Expand All @@ -21,7 +21,12 @@ export interface Props<T extends DateValue> extends UseDateRangePickerProps<T> {
selectorButtonPlacement?: "start" | "end";
}

function DateRangePicker<T extends DateValue>(props: Props<T>, ref: ForwardedRef<HTMLDivElement>) {
export type DateRangePickerProps<T extends DateValue = DateValue> = Props<T>;

const DateRangePicker = forwardRef(function DateRangePicker<T extends DateValue>(
props: DateRangePickerProps<T>,
ref: ForwardedRef<HTMLDivElement>,
) {
const {selectorButtonPlacement = "end", ...otherProps} = props;

const {
Expand Down Expand Up @@ -115,15 +120,6 @@ function DateRangePicker<T extends DateValue>(props: Props<T>, ref: ForwardedRef
{disableAnimation ? popoverContent : <AnimatePresence>{popoverContent}</AnimatePresence>}
</>
);
}
}) as <T extends DateValue>(props: DateRangePickerProps<T>) => ReactElement;

DateRangePicker.displayName = "NextUI.DateRangePicker";

export type DateRangePickerProps<T extends DateValue = DateValue> = Props<T> & {
ref?: Ref<HTMLElement>;
};

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(DateRangePicker) as <T extends DateValue>(
props: DateRangePickerProps<T>,
) => ReactElement;
export default DateRangePicker;
20 changes: 9 additions & 11 deletions packages/components/dropdown/src/dropdown-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ import {PopoverContent} from "@nextui-org/popover";
import {FocusScope} from "@react-aria/focus";
import {forwardRef} from "@nextui-org/system";
import {Menu, MenuProps} from "@nextui-org/menu";
import {ForwardedRef, ReactElement, Ref} from "react";
import {ForwardedRef, ReactElement} from "react";

import {useDropdownContext} from "./dropdown-context";

interface Props<T extends object = object> extends Omit<MenuProps<T>, "menuProps"> {}

function DropdownMenu<T extends object>(props: Props<T>, ref: ForwardedRef<HTMLUListElement>) {
export type DropdownMenuProps<T extends object = object> = Props<T>;

const DropdownMenu = forwardRef(function DropdownMenu<T extends object>(
props: DropdownMenuProps<T>,
ref: ForwardedRef<HTMLUListElement>,
) {
const {getMenuProps} = useDropdownContext();

return (
Expand All @@ -18,13 +23,6 @@ function DropdownMenu<T extends object>(props: Props<T>, ref: ForwardedRef<HTMLU
</FocusScope>
</PopoverContent>
);
}

export type DropdownMenuProps<T extends object = object> = Props<T> & {ref?: Ref<HTMLElement>};

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(DropdownMenu) as <T extends object>(
props: DropdownMenuProps<T>,
) => ReactElement;
}) as <T extends object>(props: DropdownMenuProps<T>) => ReactElement;

DropdownMenu.displayName = "NextUI.DropdownMenu";
export default DropdownMenu;
18 changes: 9 additions & 9 deletions packages/components/listbox/src/listbox.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ForwardedRef, ReactElement, Ref} from "react";
import {ForwardedRef, ReactElement} from "react";
import {forwardRef} from "@nextui-org/system";
import {mergeProps} from "@react-aria/utils";

Expand All @@ -17,7 +17,12 @@ interface Props<T> extends UseListboxProps<T> {
virtualization?: VirtualizationProps;
}

function Listbox<T extends object>(props: Props<T>, ref: ForwardedRef<HTMLUListElement>) {
export type ListboxProps<T extends object = object> = Props<T>;

const Listbox = forwardRef(function Listbox<T extends object>(
props: ListboxProps<T>,
ref: ForwardedRef<HTMLUListElement>,
) {
const {isVirtualized, ...restProps} = props;

const useListboxProps = useListbox<T>({...restProps, ref});
Expand Down Expand Up @@ -91,11 +96,6 @@ function Listbox<T extends object>(props: Props<T>, ref: ForwardedRef<HTMLUListE
{bottomContent}
</div>
);
}

Listbox.displayName = "NextUI.Listbox";

export type ListboxProps<T extends object = object> = Props<T> & {ref?: Ref<HTMLElement>};
}) as <T extends object>(props: ListboxProps<T>) => ReactElement;

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(Listbox) as <T extends object>(props: ListboxProps<T>) => ReactElement;
export default Listbox;
Loading