(react) add Modal

Here it is! Our really wanted Modal component, based on Figma sketches.
This commit is contained in:
Nathan Vasse
2024-01-18 14:38:48 +01:00
committed by NathanVss
parent 81e4da1d36
commit 1445f4a222
32 changed files with 1723 additions and 111 deletions

View File

@@ -1,9 +1,9 @@
import React, { useMemo } from "react";
import classNames from "classnames";
import { Button } from ":/components/Button";
import { AlertProps, AlertType } from ":/components/Alert/index";
import { AlertProps } from ":/components/Alert/index";
import { useCunningham } from ":/components/Provider";
import { ToastType } from ":/components/Toast/ToastProvider";
import { iconFromType } from ":/utils/VariantUtils";
export const AlertWrapper = (props: AlertProps) => {
return (
@@ -22,36 +22,6 @@ export const AlertWrapper = (props: AlertProps) => {
);
};
export const iconFromType = (type?: AlertType | ToastType) => {
switch (type) {
case AlertType.INFO:
return "info";
case AlertType.SUCCESS:
return "check_circle";
case AlertType.WARNING:
return "error_outline";
case AlertType.ERROR:
return "cancel";
default:
return "";
}
};
export const colorFromType = (type?: AlertType | ToastType) => {
switch (type) {
case AlertType.INFO:
return "info";
case AlertType.SUCCESS:
return "success";
case AlertType.WARNING:
return "warning";
case AlertType.ERROR:
return "danger";
default:
return "neutral";
}
};
export const AlertIcon = ({ type, ...props }: AlertProps) => {
const icon = useMemo(() => iconFromType(type), [type]);
if (props.icon) {

View File

@@ -1,17 +1,18 @@
import { render, screen } from "@testing-library/react";
import React from "react";
import userEvent from "@testing-library/user-event";
import { Alert, AlertType } from ":/components/Alert/index";
import { Alert } from ":/components/Alert/index";
import { Button } from ":/components/Button";
import { CunninghamProvider } from ":/components/Provider";
import { VariantType } from ":/utils/VariantUtils";
describe("<Alert/>", () => {
it.each([
[AlertType.INFO, "info"],
[AlertType.SUCCESS, "check_circle"],
[AlertType.WARNING, "error_outline"],
[AlertType.ERROR, "cancel"],
[AlertType.NEUTRAL, undefined],
[VariantType.INFO, "info"],
[VariantType.SUCCESS, "check_circle"],
[VariantType.WARNING, "error_outline"],
[VariantType.ERROR, "cancel"],
[VariantType.NEUTRAL, undefined],
])("renders % alert with according icon", (type, icon) => {
render(
<CunninghamProvider>
@@ -28,7 +29,7 @@ describe("<Alert/>", () => {
it("renders additional information", () => {
render(
<CunninghamProvider>
<Alert type={AlertType.INFO} additional="Additional information">
<Alert type={VariantType.INFO} additional="Additional information">
Alert component
</Alert>
</CunninghamProvider>,
@@ -38,7 +39,7 @@ describe("<Alert/>", () => {
it("renders primary button when primaryLabel is provided", () => {
render(
<CunninghamProvider>
<Alert type={AlertType.INFO} primaryLabel="Primary">
<Alert type={VariantType.INFO} primaryLabel="Primary">
Alert component
</Alert>
</CunninghamProvider>,
@@ -48,7 +49,7 @@ describe("<Alert/>", () => {
it("renders tertiary button when tertiaryLabel is provided", () => {
render(
<CunninghamProvider>
<Alert type={AlertType.INFO} tertiaryLabel="Tertiary">
<Alert type={VariantType.INFO} tertiaryLabel="Tertiary">
Alert component
</Alert>
</CunninghamProvider>,
@@ -59,7 +60,7 @@ describe("<Alert/>", () => {
render(
<CunninghamProvider>
<Alert
type={AlertType.INFO}
type={VariantType.INFO}
primaryLabel="Primary"
tertiaryLabel="Tertiary"
>
@@ -74,7 +75,7 @@ describe("<Alert/>", () => {
render(
<CunninghamProvider>
<Alert
type={AlertType.INFO}
type={VariantType.INFO}
buttons={
<>
<Button color="primary">Primary Custom</Button>
@@ -92,7 +93,7 @@ describe("<Alert/>", () => {
it("can close the alert non controlled", async () => {
render(
<CunninghamProvider>
<Alert type={AlertType.INFO} canClose={true}>
<Alert type={VariantType.INFO} canClose={true}>
Alert component
</Alert>
</CunninghamProvider>,
@@ -113,7 +114,7 @@ describe("<Alert/>", () => {
return (
<CunninghamProvider>
<Alert
type={AlertType.INFO}
type={VariantType.INFO}
canClose={true}
closed={closed}
onClose={(flag) => setClosed(flag)}
@@ -158,7 +159,7 @@ describe("<Alert/>", () => {
render(
<CunninghamProvider>
<Alert
type={AlertType.INFO}
type={VariantType.INFO}
additional="Additional information"
expandable={true}
>
@@ -192,7 +193,7 @@ describe("<Alert/>", () => {
return (
<CunninghamProvider>
<Alert
type={AlertType.INFO}
type={VariantType.INFO}
additional="Additional information"
expandable={true}
expanded={expanded}

View File

@@ -1,7 +1,8 @@
import { Meta, StoryObj } from "@storybook/react";
import React from "react";
import { Alert, AlertProps, AlertType } from ":/components/Alert";
import { Alert, AlertProps } from ":/components/Alert";
import { Button } from ":/components/Button";
import { VariantType } from ":/utils/VariantUtils";
const meta: Meta<typeof Alert> = {
title: "Components/Alert",
@@ -13,7 +14,7 @@ type Story = StoryObj<typeof Alert>;
export const All: Story = {
render: (args) => {
const customProps: AlertProps = { type: args.type ?? AlertType.INFO };
const customProps: AlertProps = { type: args.type ?? VariantType.INFO };
return (
<div style={{ display: "flex", gap: "1rem", flexDirection: "column" }}>
<Alert {...Info.args} primaryLabel={undefined} {...customProps} />
@@ -69,7 +70,7 @@ export const Success: Story = {
children: "Alert component Success",
canClose: true,
primaryLabel: "Primary",
type: AlertType.SUCCESS,
type: VariantType.SUCCESS,
},
};
@@ -78,7 +79,7 @@ export const Warning: Story = {
children: "Alert component Warning",
canClose: true,
primaryLabel: "Primary",
type: AlertType.WARNING,
type: VariantType.WARNING,
},
};
@@ -87,7 +88,7 @@ export const Error: Story = {
children: "Alert component Error",
canClose: true,
primaryLabel: "Primary",
type: AlertType.ERROR,
type: VariantType.ERROR,
},
};
@@ -96,7 +97,7 @@ export const Neutral: Story = {
children: "Alert component Neutral",
canClose: true,
primaryLabel: "Primary",
type: AlertType.NEUTRAL,
type: VariantType.NEUTRAL,
},
};

View File

@@ -4,14 +4,7 @@ import { useControllableState } from ":/hooks/useControllableState";
import { AlertAdditionalExpandable } from ":/components/Alert/AlertAdditionalExpandable";
import { AlertAdditional } from ":/components/Alert/AlertAdditional";
import { AlertOneLine } from ":/components/Alert/AlertOneLine";
export enum AlertType {
INFO = "info",
SUCCESS = "success",
WARNING = "warning",
ERROR = "error",
NEUTRAL = "neutral",
}
import { VariantType } from ":/utils/VariantUtils";
export interface AlertProps extends PropsWithChildren {
additional?: React.ReactNode;
@@ -31,7 +24,7 @@ export interface AlertProps extends PropsWithChildren {
tertiaryLabel?: string;
tertiaryOnClick?: ButtonProps["onClick"];
tertiaryProps?: ButtonProps;
type?: AlertType;
type?: VariantType;
}
export const Alert = (props: AlertProps) => {
@@ -42,7 +35,7 @@ export const Alert = (props: AlertProps) => {
);
const propsWithDefault = {
type: AlertType.INFO,
type: VariantType.INFO,
...props,
onClose,
};