Skip to content

Commit

Permalink
💥(react) upgrade to React 19
Browse files Browse the repository at this point in the history
  • Loading branch information
jbpenrath committed Jan 8, 2025
1 parent 0f6a8df commit 56d9ed8
Show file tree
Hide file tree
Showing 27 changed files with 1,480 additions and 1,529 deletions.
5 changes: 5 additions & 0 deletions .changeset/gorgeous-clocks-wash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@openfun/cunningham-react": major
---

Upgrade to React 19
130 changes: 63 additions & 67 deletions packages/react/src/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,80 +2,76 @@ import React, {
AnchorHTMLAttributes,
ButtonHTMLAttributes,
createElement,
forwardRef,
ReactNode,
RefAttributes,
} from "react";

type DomProps = ButtonHTMLAttributes<HTMLButtonElement> &
AnchorHTMLAttributes<HTMLAnchorElement>;

export type ButtonProps = Omit<DomProps, "color"> & {
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<DomProps, "color"> &
RefAttributes<ButtonElement> & {
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<ButtonElement, ButtonProps>(
(
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 = <span className="c__button__icon">{icon}</span>;
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 = <span className="c__button__icon">{icon}</span>;
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}
</>,
);
};
121 changes: 62 additions & 59 deletions packages/react/src/components/Forms/Checkbox/index.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -16,72 +16,75 @@ export type CheckboxOnlyProps = {
};

export type CheckboxProps = InputHTMLAttributes<HTMLInputElement> &
RefAttributes<HTMLInputElement> &
FieldProps &
CheckboxOnlyProps;

export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
(
{ indeterminate, className = "", checked, label, ...props }: CheckboxProps,
ref,
) => {
const inputRef = useRef<HTMLInputElement>();
const [value, setValue] = useState<boolean>(!!checked);
export const Checkbox = ({
indeterminate,
className = "",
checked,
label,
ref,
...props
}: CheckboxProps) => {
const inputRef = useRef<HTMLInputElement>(null);
const [value, setValue] = useState<boolean>(!!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 (
<label
className={classNames("c__checkbox", className, {
"c__checkbox--disabled": props.disabled,
"c__checkbox--full-width": props.fullWidth,
})}
>
<Field compact={true} {...props}>
<div className="c__checkbox__container">
<div className="c__checkbox__wrapper">
<input
type="checkbox"
{...inputProps}
onChange={(e) => {
setValue(e.target.checked);
props.onChange?.(e);
}}
checked={value}
ref={(checkboxRef) => {
if (typeof ref === "function") {
ref(checkboxRef);
}
inputRef.current = checkboxRef || undefined;
}}
/>
<Indeterminate />
<Checkmark />
</div>
{label && <div className="c__checkbox__label">{label}</div>}
return (
<label
className={classNames("c__checkbox", className, {
"c__checkbox--disabled": props.disabled,
"c__checkbox--full-width": props.fullWidth,
})}
>
<Field compact={true} {...props}>
<div className="c__checkbox__container">
<div className="c__checkbox__wrapper">
<input
type="checkbox"
{...inputProps}
onChange={(e) => {
setValue(e.target.checked);
props.onChange?.(e);
}}
checked={value}
ref={(checkboxRef) => {
if (typeof ref === "function") {
ref(checkboxRef);
}
inputRef.current = checkboxRef || null;
}}
/>
<Indeterminate />
<Checkmark />
</div>
</Field>
</label>
);
},
);
{label && <div className="c__checkbox__label">{label}</div>}
</div>
</Field>
</label>
);
};

export const CheckboxGroup = ({
children,
Expand Down
Loading

0 comments on commit 56d9ed8

Please sign in to comment.