Skip to content

Commit

Permalink
chore!: use ref prop instead of forwardRef (#1515)
Browse files Browse the repository at this point in the history
* chore(components): use `ref` prop instead of `forwardRef`

* chore(icons): add `ref` prop

* chore!: drop React 18 support

* chore: add changeset
  • Loading branch information
Niznikr authored Jan 8, 2025
1 parent 7abe491 commit fe07097
Show file tree
Hide file tree
Showing 59 changed files with 834 additions and 837 deletions.
6 changes: 6 additions & 0 deletions .changeset/angry-moose-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@launchpad-ui/components": minor
"@launchpad-ui/icons": minor
---

Use `ref` prop instead of `forwardRef` and drop React 18 support
4 changes: 2 additions & 2 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
"react-router": "7.0.1"
},
"peerDependencies": {
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"react": "19.0.0",
Expand Down
30 changes: 13 additions & 17 deletions packages/components/src/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import type { VariantProps } from 'class-variance-authority';
import type { ForwardedRef, HTMLAttributes } from 'react';
import type { HTMLAttributes, RefObject } from 'react';

import { StatusIcon } from '@launchpad-ui/icons';
import { useControlledState } from '@react-stately/utils';
import { cva } from 'class-variance-authority';
import { forwardRef } from 'react';
import { HeadingContext, Provider } from 'react-aria-components';

import { IconButton } from './IconButton';
Expand Down Expand Up @@ -37,21 +36,20 @@ interface AlertProps extends HTMLAttributes<HTMLDivElement>, AlertVariants {
isDismissable?: boolean;
isOpen?: boolean;
onDismiss?: () => void;
ref?: RefObject<HTMLDivElement | null>;
}

const _Alert = (
{
className,
children,
status = 'neutral',
variant = 'default',
isDismissable,
isOpen,
onDismiss,
...props
}: AlertProps,
ref: ForwardedRef<HTMLDivElement>,
) => {
const Alert = ({
className,
children,
status = 'neutral',
variant = 'default',
isDismissable,
isOpen,
onDismiss,
ref,
...props
}: AlertProps) => {
const [open, setOpen] = useControlledState(isOpen, true, (val) => !val && onDismiss?.());

return open ? (
Expand All @@ -75,7 +73,5 @@ const _Alert = (
) : null;
};

const Alert = forwardRef(_Alert);

export { Alert };
export type { AlertProps };
42 changes: 23 additions & 19 deletions packages/components/src/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type { forwardRefType } from '@react-types/shared';
import type { ForwardedRef } from 'react';
import type { BreadcrumbProps, BreadcrumbsProps, ContextValue } from 'react-aria-components';
import type { RefObject } from 'react';
import type {
BreadcrumbProps as AriaBreadcrumbProps,
BreadcrumbsProps as AriaBreadcrumbsProps,
ContextValue,
} from 'react-aria-components';
import type { LinkProps } from './Link';

import { cva } from 'class-variance-authority';
import { createContext, forwardRef } from 'react';
import { createContext } from 'react';
import {
Breadcrumb as AriaBreadcrumb,
Breadcrumbs as AriaBreadcrumbs,
Expand All @@ -19,21 +22,29 @@ const crumb = cva(styles.crumb);

const LinkContext = createContext<ContextValue<LinkProps, HTMLAnchorElement>>(null);

const _Breadcrumbs = <T extends object>(
{ className, ...props }: BreadcrumbsProps<T>,
ref: ForwardedRef<HTMLOListElement>,
) => {
return <AriaBreadcrumbs {...props} ref={ref} className={crumbs({ className })} />;
};
interface BreadcrumbsProps<T extends object> extends AriaBreadcrumbsProps<T> {
ref?: RefObject<HTMLOListElement | null>;
}

interface BreadcrumbProps extends AriaBreadcrumbProps {
ref?: RefObject<HTMLLIElement | null>;
}

/**
* Breadcrumbs display a hierarchy of links to the current page or resource in an application.
*
* https://react-spectrum.adobe.com/react-aria/Breadcrumbs.html
*/
const Breadcrumbs = (forwardRef as forwardRefType)(_Breadcrumbs);
const Breadcrumbs = <T extends object>({ className, ref, ...props }: BreadcrumbsProps<T>) => {
return <AriaBreadcrumbs {...props} ref={ref} className={crumbs({ className })} />;
};

const _Breadcrumb = (props: BreadcrumbProps, ref: ForwardedRef<HTMLLIElement>) => {
/**
* A Breadcrumb represents an individual item in a `<Breadcrumbs>` list.
*
* https://react-spectrum.adobe.com/react-aria/Breadcrumbs.html
*/
const Breadcrumb = ({ ref, ...props }: BreadcrumbProps) => {
return (
<AriaBreadcrumb
{...props}
Expand All @@ -49,12 +60,5 @@ const _Breadcrumb = (props: BreadcrumbProps, ref: ForwardedRef<HTMLLIElement>) =
);
};

/**
* A Breadcrumb represents an individual item in a `<Breadcrumbs>` list.
*
* https://react-spectrum.adobe.com/react-aria/Breadcrumbs.html
*/
const Breadcrumb = forwardRef(_Breadcrumb);

export { Breadcrumbs, Breadcrumb, LinkContext };
export type { BreadcrumbsProps, BreadcrumbProps };
25 changes: 11 additions & 14 deletions packages/components/src/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { VariantProps } from 'class-variance-authority';
import type { ForwardedRef } from 'react';
import type { RefObject } from 'react';
import type { ButtonProps as AriaButtonProps } from 'react-aria-components';

import { cva, cx } from 'class-variance-authority';
import { forwardRef, useContext } from 'react';
import { useContext } from 'react';
import {
Button as AriaButton,
Provider,
Expand Down Expand Up @@ -40,12 +40,16 @@ const button = cva(styles.base, {
});

interface ButtonVariants extends VariantProps<typeof button> {}
interface ButtonProps extends AriaButtonProps, ButtonVariants {}
interface ButtonProps extends AriaButtonProps, ButtonVariants {
ref?: RefObject<HTMLButtonElement | null>;
}

const _Button = (
{ size = 'medium', variant = 'default', ...props }: ButtonProps,
ref: ForwardedRef<HTMLButtonElement>,
) => {
/**
* A button allows a user to perform an action, with mouse, touch, and keyboard interactions.
*
* https://react-spectrum.adobe.com/react-aria/Button.html
*/
const Button = ({ size = 'medium', variant = 'default', ref, ...props }: ButtonProps) => {
const selectContext = useSlottedContext(SelectContext);
const state = useContext(SelectStateContext);
const ctx = useContext(PerceivableContext);
Expand Down Expand Up @@ -73,12 +77,5 @@ const _Button = (
);
};

/**
* A button allows a user to perform an action, with mouse, touch, and keyboard interactions.
*
* https://react-spectrum.adobe.com/react-aria/Button.html
*/
const Button = forwardRef(_Button);

export { Button, button };
export type { ButtonProps, ButtonVariants };
16 changes: 8 additions & 8 deletions packages/components/src/ButtonGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import type { Orientation } from '@react-types/shared';
import type { VariantProps } from 'class-variance-authority';
import type { ForwardedRef } from 'react';
import type { RefObject } from 'react';
import type { GroupProps } from 'react-aria-components';

import { cva } from 'class-variance-authority';
import { forwardRef } from 'react';
import {
ButtonContext,
Group,
Expand Down Expand Up @@ -34,12 +33,15 @@ const buttonGroup = cva(styles.base, {

interface ButtonGroupProps extends GroupProps, VariantProps<typeof buttonGroup> {
orientation?: Orientation | null;
ref?: RefObject<HTMLDivElement | null>;
}

const _ButtonGroup = (
{ spacing = 'basic', orientation = 'horizontal', ...props }: ButtonGroupProps,
ref: ForwardedRef<HTMLDivElement>,
) => {
const ButtonGroup = ({
spacing = 'basic',
orientation = 'horizontal',
ref,
...props
}: ButtonGroupProps) => {
return (
<Group
{...props}
Expand All @@ -63,7 +65,5 @@ const _ButtonGroup = (
);
};

const ButtonGroup = forwardRef(_ButtonGroup);

export { ButtonGroup };
export type { ButtonGroupProps };
72 changes: 34 additions & 38 deletions packages/components/src/Calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import type { CalendarDate } from '@internationalized/date';
import type { RangeValue } from '@react-types/shared';
import type { ForwardedRef, HTMLAttributes } from 'react';
import type { HTMLAttributes, RefObject } from 'react';
import type {
CalendarCellProps,
CalendarCellProps as AriaCalendarCellProps,
CalendarProps as AriaCalendarProps,
RangeCalendarProps as AriaRangeCalendarProps,
CalendarGridBodyProps,
CalendarGridHeaderProps,
CalendarGridProps,
CalendarHeaderCellProps,
CalendarProps,
DateRange,
DateValue,
RangeCalendarProps,
} from 'react-aria-components';
import type { ButtonProps } from './Button';

import { cva, cx } from 'class-variance-authority';
import { forwardRef, useState } from 'react';
import { useState } from 'react';
import {
Calendar as AriaCalendar,
CalendarCell as AriaCalendarCell,
Expand All @@ -35,20 +35,37 @@ import {
import { Button, button } from './Button';
import styles from './styles/Calendar.module.css';

interface CalendarPickerProps extends HTMLAttributes<HTMLDivElement> {}
interface CalendarPickerProps extends HTMLAttributes<HTMLDivElement> {
ref?: RefObject<HTMLDivElement | null>;
}

interface PresetProps extends Omit<ButtonProps, 'value'> {
value: CalendarDate | RangeValue<CalendarDate>;
ref?: RefObject<HTMLButtonElement | null>;
}

const calendar = cva(styles.calendar);
const cell = cva(styles.cell);
const range = cva(styles.range);

const _Calendar = <T extends DateValue>(
props: CalendarProps<T>,
ref: ForwardedRef<HTMLDivElement>,
) => {
interface CalendarProps<T extends DateValue> extends AriaCalendarProps<T> {
ref?: RefObject<HTMLDivElement | null>;
}

interface CalendarCellProps extends AriaCalendarCellProps {
ref?: RefObject<HTMLTableCellElement | null>;
}

interface RangeCalendarProps<T extends DateValue> extends AriaRangeCalendarProps<T> {
ref?: RefObject<HTMLDivElement | null>;
}

/**
* A calendar displays one or more date grids and allows users to select a single date.
*
* https://react-spectrum.adobe.com/react-aria/Calendar.html
*/
const Calendar = <T extends DateValue>({ ref, ...props }: CalendarProps<T>) => {
return (
<AriaCalendar
{...props}
Expand All @@ -61,13 +78,11 @@ const _Calendar = <T extends DateValue>(
};

/**
* A calendar displays one or more date grids and allows users to select a single date.
* A calendar cell displays a date cell within a calendar grid which can be selected by the user.
*
* https://react-spectrum.adobe.com/react-aria/Calendar.html
*/
const Calendar = forwardRef(_Calendar);

const _CalendarCell = (props: CalendarCellProps, ref: ForwardedRef<HTMLTableCellElement>) => {
const CalendarCell = ({ ref, ...props }: CalendarCellProps) => {
return (
<AriaCalendarCell
{...props}
Expand All @@ -80,16 +95,11 @@ const _CalendarCell = (props: CalendarCellProps, ref: ForwardedRef<HTMLTableCell
};

/**
* A calendar cell displays a date cell within a calendar grid which can be selected by the user.
* A range calendar displays one or more date grids and allows users to select a contiguous range of dates.
*
* https://react-spectrum.adobe.com/react-aria/Calendar.html
* https://react-spectrum.adobe.com/react-aria/RangeCalendar.html
*/
const CalendarCell = forwardRef(_CalendarCell);

const _RangeCalendar = <T extends DateValue>(
props: RangeCalendarProps<T>,
ref: ForwardedRef<HTMLDivElement>,
) => {
const RangeCalendar = <T extends DateValue>({ ref, ...props }: RangeCalendarProps<T>) => {
return (
<AriaRangeCalendar
{...props}
Expand All @@ -101,17 +111,7 @@ const _RangeCalendar = <T extends DateValue>(
);
};

/**
* A range calendar displays one or more date grids and allows users to select a contiguous range of dates.
*
* https://react-spectrum.adobe.com/react-aria/RangeCalendar.html
*/
const RangeCalendar = forwardRef(_RangeCalendar);

const _CalendarPicker = (
{ children, className, ...props }: CalendarPickerProps,
ref: ForwardedRef<HTMLDivElement>,
) => {
const CalendarPicker = ({ children, className, ref, ...props }: CalendarPickerProps) => {
const [value, onChange] = useState<DateValue>();
const [range, onChangeRange] = useState<DateRange | null>();
const [focusedValue, onFocusChange] = useState<DateValue>();
Expand All @@ -133,9 +133,7 @@ const _CalendarPicker = (
);
};

const CalendarPicker = forwardRef(_CalendarPicker);

const _Preset = ({ value, ...props }: PresetProps, ref: ForwardedRef<HTMLButtonElement>) => {
const Preset = ({ value, ref, ...props }: PresetProps) => {
const context = useSlottedContext(CalendarContext);
const rangeContext = useSlottedContext(RangeCalendarContext);
const onPress = () => {
Expand All @@ -150,8 +148,6 @@ const _Preset = ({ value, ...props }: PresetProps, ref: ForwardedRef<HTMLButtonE
return <Button ref={ref} size="small" variant="minimal" {...props} onPress={onPress} />;
};

const Preset = forwardRef(_Preset);

export {
Calendar,
CalendarCell,
Expand Down
Loading

0 comments on commit fe07097

Please sign in to comment.