diff --git a/.changeset/gorgeous-clocks-wash.md b/.changeset/gorgeous-clocks-wash.md new file mode 100644 index 0000000..81b21db --- /dev/null +++ b/.changeset/gorgeous-clocks-wash.md @@ -0,0 +1,5 @@ +--- +"@openfun/cunningham-react": major +--- + +Upgrade to React 19 diff --git a/packages/react/src/components/Button/index.tsx b/packages/react/src/components/Button/index.tsx index a513e98..0ff2802 100644 --- a/packages/react/src/components/Button/index.tsx +++ b/packages/react/src/components/Button/index.tsx @@ -2,80 +2,76 @@ import React, { AnchorHTMLAttributes, ButtonHTMLAttributes, createElement, - forwardRef, ReactNode, + RefAttributes, } from "react"; type DomProps = ButtonHTMLAttributes & AnchorHTMLAttributes; -export type ButtonProps = Omit & { - size?: "medium" | "small" | "nano"; - color?: - | "primary" - | "primary-text" - | "secondary" - | "tertiary" - | "tertiary-text" - | "danger"; - icon?: ReactNode; - iconPosition?: "left" | "right"; - active?: boolean; - fullWidth?: boolean; -}; - export type ButtonElement = HTMLButtonElement & HTMLAnchorElement; +export type ButtonProps = Omit & + RefAttributes & { + size?: "medium" | "small" | "nano"; + color?: + | "primary" + | "primary-text" + | "secondary" + | "tertiary" + | "tertiary-text" + | "danger"; + icon?: ReactNode; + iconPosition?: "left" | "right"; + active?: boolean; + fullWidth?: boolean; + }; -export const Button = forwardRef( - ( +export const Button = ({ + children, + color = "primary", + size = "medium", + iconPosition = "left", + icon, + active, + className, + fullWidth, + ref, + ...props +}: ButtonProps) => { + const classes = [ + "c__button", + "c__button--" + color, + "c__button--" + size, + className, + ]; + if (icon && children) { + classes.push("c__button--with-icon--" + iconPosition); + } + if (icon && !children) { + classes.push("c__button--icon-only"); + } + if (active) { + classes.push("c__button--active"); + } + if (fullWidth) { + classes.push("c__button--full-width"); + } + if (["primary-text", "tertiary-text"].includes(color)) { + classes.push("c__button--text"); + } + const iconElement = {icon}; + const tagName = props.href ? "a" : "button"; + return createElement( + tagName, { - children, - color = "primary", - size = "medium", - iconPosition = "left", - icon, - active, - className, - fullWidth, - ...props + className: classes.join(" "), + ...props, + ref, }, - ref, - ) => { - const classes = [ - "c__button", - "c__button--" + color, - "c__button--" + size, - className, - ]; - if (icon && children) { - classes.push("c__button--with-icon--" + iconPosition); - } - if (icon && !children) { - classes.push("c__button--icon-only"); - } - if (active) { - classes.push("c__button--active"); - } - if (fullWidth) { - classes.push("c__button--full-width"); - } - if (["primary-text", "tertiary-text"].includes(color)) { - classes.push("c__button--text"); - } - const iconElement = {icon}; - const tagName = props.href ? "a" : "button"; - return createElement( - tagName, - { - className: classes.join(" "), - ...props, - ref, - }, - <> - {!!icon && iconPosition === "left" && iconElement} - {children} - {!!icon && iconPosition === "right" && iconElement} - , - ); - }, -); + <> + {!!icon && iconPosition === "left" && iconElement} + {children} + {!!icon && iconPosition === "right" && iconElement} + , + ); +}; diff --git a/packages/react/src/components/Forms/Checkbox/index.tsx b/packages/react/src/components/Forms/Checkbox/index.tsx index 98a914d..85ae329 100644 --- a/packages/react/src/components/Forms/Checkbox/index.tsx +++ b/packages/react/src/components/Forms/Checkbox/index.tsx @@ -1,11 +1,11 @@ import React, { InputHTMLAttributes, PropsWithChildren, - forwardRef, useEffect, useRef, useState, ReactNode, + RefAttributes, } from "react"; import classNames from "classnames"; import { Field, FieldProps } from ":/components/Forms/Field"; @@ -16,72 +16,75 @@ export type CheckboxOnlyProps = { }; export type CheckboxProps = InputHTMLAttributes & + RefAttributes & FieldProps & CheckboxOnlyProps; -export const Checkbox = forwardRef( - ( - { indeterminate, className = "", checked, label, ...props }: CheckboxProps, - ref, - ) => { - const inputRef = useRef(); - const [value, setValue] = useState(!!checked); +export const Checkbox = ({ + indeterminate, + className = "", + checked, + label, + ref, + ...props +}: CheckboxProps) => { + const inputRef = useRef(null); + const [value, setValue] = useState(!!checked); - useEffect(() => { - setValue(!!checked); - }, [checked]); + useEffect(() => { + setValue(!!checked); + }, [checked]); - useEffect(() => { - if (inputRef.current) { - inputRef.current.indeterminate = !!indeterminate; - } - }, [indeterminate]); + useEffect(() => { + if (inputRef.current) { + inputRef.current.indeterminate = !!indeterminate; + } + }, [indeterminate]); - const { - compact, - fullWidth, - rightText, - state, - text, - textItems, - ...inputProps - } = props; + const { + compact, + fullWidth, + rightText, + state, + text, + textItems, + ...inputProps + } = props; - return ( -