diff --git a/.changeset/breezy-llamas-fail.md b/.changeset/breezy-llamas-fail.md
new file mode 100644
index 0000000..193bb30
--- /dev/null
+++ b/.changeset/breezy-llamas-fail.md
@@ -0,0 +1,5 @@
+---
+"@openfun/cunningham-react": minor
+---
+
+render Button as link
diff --git a/packages/react/src/components/Button/index.scss b/packages/react/src/components/Button/index.scss
index 5feea48..accfbcc 100644
--- a/packages/react/src/components/Button/index.scss
+++ b/packages/react/src/components/Button/index.scss
@@ -4,7 +4,9 @@
border: thin solid transparent;
box-sizing: border-box;
cursor: pointer;
- display: flex;
+ display: inline-flex;
+ // When button is rendered as link.
+ text-decoration: none;
font-weight: var(--c--components--button--font-weight);
font-family: var(--c--components--button--font-family);
transition: all var(--c--theme--transitions--duration) var(--c--theme--transitions--ease-out);
diff --git a/packages/react/src/components/Button/index.spec.tsx b/packages/react/src/components/Button/index.spec.tsx
index 91f4981..1891254 100644
--- a/packages/react/src/components/Button/index.spec.tsx
+++ b/packages/react/src/components/Button/index.spec.tsx
@@ -65,6 +65,21 @@ describe("", () => {
expect(handleClick).not.toHaveBeenCalled();
});
+ it("renders as link when href is used", () => {
+ render(
+ ,
+ );
+ const button = screen.getByRole("link", { name: "Open link" });
+ expect(button).toHaveAttribute("target", "_blank");
+ expect(button).toHaveAttribute("rel", "noopener noreferrer");
+ });
+
it("uses custom token", async () => {
await buildTheme();
const tokens = await loadTokens();
diff --git a/packages/react/src/components/Button/index.stories.tsx b/packages/react/src/components/Button/index.stories.tsx
index 235b1c4..81c5c1a 100644
--- a/packages/react/src/components/Button/index.stories.tsx
+++ b/packages/react/src/components/Button/index.stories.tsx
@@ -103,3 +103,14 @@ export const IconOnly: Story = {
color: "primary",
},
};
+
+export const AsLink: Story = {
+ args: {
+ children: "Go to fun-mooc.fr",
+ icon: link,
+ color: "primary",
+ href: "https://www.fun-mooc.fr/",
+ target: "_blank",
+ rel: "noopener noreferrer",
+ },
+};
diff --git a/packages/react/src/components/Button/index.tsx b/packages/react/src/components/Button/index.tsx
index 7ecf8dd..545c3fc 100644
--- a/packages/react/src/components/Button/index.tsx
+++ b/packages/react/src/components/Button/index.tsx
@@ -1,15 +1,24 @@
-import React, { ButtonHTMLAttributes, forwardRef, ReactNode } from "react";
+import React, {
+ AnchorHTMLAttributes,
+ ButtonHTMLAttributes,
+ createElement,
+ forwardRef,
+ ReactNode,
+} from "react";
-export interface ButtonProps extends ButtonHTMLAttributes {
- color?: "primary" | "secondary" | "tertiary" | "danger";
- size?: "medium" | "small" | "nano";
- icon?: ReactNode;
- iconPosition?: "left" | "right";
- active?: boolean;
- fullWidth?: boolean;
-}
+export type ButtonProps = ButtonHTMLAttributes &
+ AnchorHTMLAttributes & {
+ color?: "primary" | "secondary" | "tertiary" | "danger";
+ size?: "medium" | "small" | "nano";
+ icon?: ReactNode;
+ iconPosition?: "left" | "right";
+ active?: boolean;
+ fullWidth?: boolean;
+ };
-export const Button = forwardRef(
+export type ButtonElement = HTMLButtonElement & HTMLAnchorElement;
+
+export const Button = forwardRef(
(
{
children,
@@ -43,13 +52,19 @@ export const Button = forwardRef(
classes.push("c__button--full-width");
}
const iconElement = {icon};
- // const iconElement = icon;
- return (
-
+ >,
);
},
);
diff --git a/packages/react/src/components/Forms/DatePicker/CalendarCell.tsx b/packages/react/src/components/Forms/DatePicker/CalendarCell.tsx
index fa3cc7c..a935317 100644
--- a/packages/react/src/components/Forms/DatePicker/CalendarCell.tsx
+++ b/packages/react/src/components/Forms/DatePicker/CalendarCell.tsx
@@ -8,7 +8,7 @@ import {
isToday,
} from "@internationalized/date";
import { CalendarState, RangeCalendarState } from "@react-stately/calendar";
-import { Button } from ":/components/Button";
+import { Button, ButtonElement } from ":/components/Button";
interface CalendarCellProps {
state: CalendarState | RangeCalendarState;
@@ -20,7 +20,7 @@ const isRangeCalendar = (object: any): object is RangeCalendarState => {
};
export const CalendarCell = ({ state, date }: CalendarCellProps) => {
- const ref = useRef(null);
+ const ref = useRef(null);
const {
cellProps,
buttonProps,