diff --git a/govtool/frontend/.storybook/preview.tsx b/govtool/frontend/.storybook/preview.tsx
index f3deaefc6..406ac7970 100644
--- a/govtool/frontend/.storybook/preview.tsx
+++ b/govtool/frontend/.storybook/preview.tsx
@@ -1,8 +1,12 @@
+import React from "react";
import type { Preview } from "@storybook/react";
import { ThemeProvider } from "@emotion/react";
import { theme } from "../src/theme";
import { MemoryRouter, Routes, Route } from "react-router-dom";
import { QueryClient, QueryClientProvider } from "react-query";
+import { I18nextProvider } from "react-i18next";
+import i18n from "../src/i18n";
+import { ModalProvider } from "../src/context/modal";
const queryClient = new QueryClient();
@@ -19,26 +23,30 @@ const preview: Preview = {
decorators: [
(Story) => (
-
-
-
-
-
-
- }
- />
-
-
-
+
+
+
+
+
+
+
+
+ }
+ />
+
+
+
+
+
),
],
diff --git a/govtool/frontend/src/stories/DashboardCard.stories.ts b/govtool/frontend/src/stories/DashboardCard.stories.ts
index 21bac97e4..fc47278eb 100644
--- a/govtool/frontend/src/stories/DashboardCard.stories.ts
+++ b/govtool/frontend/src/stories/DashboardCard.stories.ts
@@ -21,9 +21,7 @@ export const DashboardCardComponent: Story = {
args: {
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
firstButtonLabel: "first button",
- imageHeight: 80,
imageURL: IMAGES.govActionDelegateImage,
- imageWidth: 115,
secondButtonLabel: "second button",
title: "Action card",
},
@@ -38,13 +36,22 @@ export const DashboardCardComponent: Story = {
},
};
+export const WithDRepIdDashboardCardComponent: Story = {
+ args: {
+ description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
+ firstButtonLabel: "first button",
+ imageURL: IMAGES.govActionDelegateImage,
+ secondButtonLabel: "second button",
+ title: "Action card",
+ cardId: "drep1gwsw9ckkhuwscj9savt5f7u9xsrudw209hne7pggcktzuw5sv32",
+ },
+};
+
export const isLoadingDashboardCard: Story = {
args: {
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
firstButtonLabel: "first button",
- imageHeight: 80,
imageURL: IMAGES.govActionDelegateImage,
- imageWidth: 115,
secondButtonLabel: "second button",
title: "Action card",
isLoading: true,
@@ -62,9 +69,7 @@ export const isProgressDashboardCard: Story = {
args: {
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
firstButtonLabel: "first button",
- imageHeight: 80,
imageURL: IMAGES.govActionDelegateImage,
- imageWidth: 115,
secondButtonLabel: "second button",
title: "Action card",
inProgress: true,
diff --git a/govtool/frontend/src/stories/DashboardTopNav.stories.ts b/govtool/frontend/src/stories/DashboardTopNav.stories.ts
index 06508f3aa..3ecbb15b7 100644
--- a/govtool/frontend/src/stories/DashboardTopNav.stories.ts
+++ b/govtool/frontend/src/stories/DashboardTopNav.stories.ts
@@ -1,7 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react";
import { DashboardTopNav } from "@organisms";
-import { IMAGES } from "@/consts";
import { within, userEvent, waitFor, screen } from "@storybook/testing-library";
import { expect } from "@storybook/jest";
@@ -15,7 +14,7 @@ export default meta;
type Story = StoryObj;
export const DashboardTopNavComponent: Story = {
- args: { title: "Example title", isDrawer: true },
+ args: { title: "Example title" },
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(canvas.getByText("Example title")).toBeInTheDocument();
@@ -31,16 +30,3 @@ export const DashboardTopNavComponent: Story = {
});
},
};
-
-export const DashboardTopNavWithIcon: Story = {
- args: {
- title: "Example title",
- isDrawer: true,
- imageSRC: IMAGES.appLogoWithoutText,
- imageHeight: 24,
- },
- play: async ({ canvasElement }) => {
- const canvas = within(canvasElement);
- expect(canvas.getByRole("img")).toBeInTheDocument();
- },
-};
diff --git a/govtool/frontend/src/stories/DelegateActionRadio.stories.ts b/govtool/frontend/src/stories/DelegateActionRadio.stories.ts
index a05563d28..49c24295c 100644
--- a/govtool/frontend/src/stories/DelegateActionRadio.stories.ts
+++ b/govtool/frontend/src/stories/DelegateActionRadio.stories.ts
@@ -68,3 +68,19 @@ export const ActionRadioActive: Story = {
);
},
};
+
+export const ActionRadioOnlyTitle: Story = {
+ args: {
+ title: "Title",
+ value: "",
+ isChecked: false,
+ },
+};
+
+export const ActionRadioOnlyTitleChecked: Story = {
+ args: {
+ title: "Title",
+ value: "",
+ isChecked: true,
+ },
+};
diff --git a/govtool/frontend/src/stories/Input.stories.tsx b/govtool/frontend/src/stories/Input.stories.tsx
index cbe95a400..95a134c60 100644
--- a/govtool/frontend/src/stories/Input.stories.tsx
+++ b/govtool/frontend/src/stories/Input.stories.tsx
@@ -60,3 +60,8 @@ ErrorAndLabel.play = async ({ canvasElement }) => {
expect(canvas.getByText("Label")).toBeInTheDocument();
expect(canvas.getByTestId("error-message-error")).toBeInTheDocument();
};
+
+export const WithHelpfulText = Template.bind({});
+WithHelpfulText.args = {
+ helpfulText: "Helpful text",
+};
diff --git a/govtool/frontend/src/stories/LinkWithIcon.stories.tsx b/govtool/frontend/src/stories/LinkWithIcon.stories.tsx
new file mode 100644
index 000000000..83e533f25
--- /dev/null
+++ b/govtool/frontend/src/stories/LinkWithIcon.stories.tsx
@@ -0,0 +1,26 @@
+import { Meta, StoryObj } from "@storybook/react";
+import { LinkWithIcon } from "@molecules";
+import { ICONS } from "@consts";
+
+const meta: Meta = {
+ title: "Example/LinkWithIcon",
+ component: LinkWithIcon,
+ parameters: {
+ layout: "centered",
+ },
+};
+
+export default meta;
+
+export const Default: StoryObj = {
+ args: {
+ label: "Default Link",
+ },
+};
+
+export const WithCustomIcon: StoryObj = {
+ args: {
+ label: "Custom Icon Link",
+ icon: ,
+ },
+};
diff --git a/govtool/frontend/src/stories/LoadingButton.stories.tsx b/govtool/frontend/src/stories/LoadingButton.stories.tsx
new file mode 100644
index 000000000..935014cd1
--- /dev/null
+++ b/govtool/frontend/src/stories/LoadingButton.stories.tsx
@@ -0,0 +1,31 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+import { LoadingButton } from "@atoms";
+
+const meta = {
+ title: "Example/LoadingButton",
+ component: LoadingButton,
+ parameters: {
+ layout: "centered",
+ },
+ tags: ["autodocs"],
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Primary: Story = {
+ args: {
+ children: "Button",
+ variant: "contained",
+ isLoading: false,
+ },
+};
+
+export const Loading: Story = {
+ args: {
+ children: "Button",
+ variant: "contained",
+ isLoading: true,
+ },
+};
diff --git a/govtool/frontend/src/stories/Step.stories.tsx b/govtool/frontend/src/stories/Step.stories.tsx
new file mode 100644
index 000000000..aecebae56
--- /dev/null
+++ b/govtool/frontend/src/stories/Step.stories.tsx
@@ -0,0 +1,62 @@
+import { Meta, StoryObj } from "@storybook/react";
+import { Button } from "@atoms";
+import OpenInNewIcon from "@mui/icons-material/OpenInNew";
+
+import { Field, Step } from "@molecules";
+
+const meta: Meta = {
+ title: "Example/Step",
+ component: Step,
+ parameters: {
+ layout: "centered",
+ },
+};
+
+export default meta;
+
+export const WithButton: StoryObj = {
+ args: {
+ label: "Download this file",
+ stepNumber: 1,
+ component: (
+
+ ),
+ },
+};
+
+export const WithIconButton: StoryObj = {
+ args: {
+ label:
+ "Save this file in a location that provides a public URL (ex. github)",
+ stepNumber: 2,
+ component: (
+
+ }
+ size="extraLarge"
+ sx={{ width: "fit-content" }}
+ variant="text"
+ >
+ Read full guide
+
+ ),
+ },
+};
+
+export const WithInput: StoryObj = {
+ args: {
+ label:
+ "Save this file in a location that provides a public URL (ex. github)",
+ stepNumber: 2,
+ component: ,
+ },
+};
diff --git a/govtool/frontend/src/stories/TextArea.stories.tsx b/govtool/frontend/src/stories/TextArea.stories.tsx
new file mode 100644
index 000000000..8f6cc178b
--- /dev/null
+++ b/govtool/frontend/src/stories/TextArea.stories.tsx
@@ -0,0 +1,42 @@
+import type { Meta, StoryFn } from "@storybook/react";
+
+import { Field } from "@molecules";
+import { ComponentProps } from "react";
+
+const meta: Meta = {
+ title: "Example/TextArea",
+ component: Field.TextArea,
+ parameters: {
+ layout: "centered",
+ },
+ tags: ["autodocs"],
+};
+
+export default meta;
+
+const Template: StoryFn> = (args) => {
+ return ;
+};
+
+export const Default = Template.bind({});
+
+export const WithLabel = Template.bind({});
+WithLabel.args = {
+ label: "Label",
+};
+
+export const WithHelpfulText = Template.bind({});
+WithHelpfulText.args = {
+ helpfulText: "Helpful text here",
+};
+
+export const Error = Template.bind({});
+Error.args = {
+ errorMessage: "Error message",
+};
+
+export const ErrorAndLabel = Template.bind({});
+ErrorAndLabel.args = {
+ errorMessage: "Error message",
+ label: "Label",
+};
diff --git a/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx b/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx
index dc2df8b5d..236943ac5 100644
--- a/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx
+++ b/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx
@@ -1,28 +1,22 @@
-import { ComponentProps, useEffect } from "react";
-import { Story, Meta, StoryFn } from "@storybook/react";
+import { useEffect } from "react";
+import { Meta, StoryFn } from "@storybook/react";
import { Modal } from "@atoms";
import { ExternalLinkModal, ExternalLinkModalState } from "@organisms";
-import { ModalProvider, useModal } from "../../context/modal";
+import { useModal } from "../../context/modal";
import { userEvent, within, screen, waitFor } from "@storybook/testing-library";
import { expect, jest } from "@storybook/jest";
+import { callAll } from "@/utils";
const meta = {
title: "Example/Modals/ExternalLinkModal",
component: ExternalLinkModal,
- decorators: [
- (Story) => (
-
-
-
- ),
- ],
} satisfies Meta;
export default meta;
const Template: StoryFn = (args) => {
- const { openModal, modal, closeModal } = useModal();
+ const { openModal, modal, modals } = useModal();
const open = () => {
openModal({
@@ -40,12 +34,18 @@ const Template: StoryFn = (args) => {
- {modal?.component && (
+ {modals[modal.type]?.component && (
+ openModal({ type: "none", state: null })
+ )
+ : undefined
+ }
>
- {modal.component}
+ {modals[modal.type]?.component ?? <>>}
)}
>
diff --git a/govtool/frontend/src/stories/modals/StatusModal.stories.tsx b/govtool/frontend/src/stories/modals/StatusModal.stories.tsx
index 24bb364b1..d7c0b56ce 100644
--- a/govtool/frontend/src/stories/modals/StatusModal.stories.tsx
+++ b/govtool/frontend/src/stories/modals/StatusModal.stories.tsx
@@ -1,22 +1,16 @@
import { useEffect } from "react";
-import { Story, Meta, StoryFn } from "@storybook/react";
+import { Meta, StoryFn } from "@storybook/react";
+import { expect } from "@storybook/jest";
+import { within, waitFor, screen, userEvent } from "@storybook/testing-library";
import { Modal } from "@atoms";
import { StatusModal, StatusModalState } from "@organisms";
-import { ModalProvider, useModal } from "../../context/modal";
-import { within, waitFor, screen, userEvent } from "@storybook/testing-library";
-import { expect } from "@storybook/jest";
+import { useModal } from "../../context/modal";
+import { callAll } from "@utils";
const meta = {
title: "Example/Modals/StatusModal",
component: StatusModal,
- decorators: [
- (Story) => (
-
-
-
- ),
- ],
} satisfies Meta;
export default meta;
@@ -40,7 +34,7 @@ const performCommonAction = async (canvas: any, args: any) => {
});
};
const Template: StoryFn = (args) => {
- const { openModal, modal, closeModal } = useModal();
+ const { openModal, modal, modals, closeModal } = useModal();
const open = () => {
openModal({
@@ -67,12 +61,18 @@ const Template: StoryFn = (args) => {
- {modal?.component && (
+ {modals[modal.type]?.component && (
+ openModal({ type: "none", state: null })
+ )
+ : undefined
+ }
>
- {modal.component}
+ {modals[modal.type]?.component ?? <>>}
)}
>
diff --git a/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx b/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx
index e331a14bb..1181fb143 100644
--- a/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx
+++ b/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx
@@ -1,28 +1,22 @@
import { useEffect } from "react";
-import { Story, Meta, StoryFn } from "@storybook/react";
+import { Meta, StoryFn } from "@storybook/react";
+import { expect, jest } from "@storybook/jest";
+import { userEvent, waitFor, within, screen } from "@storybook/testing-library";
import { Modal } from "@atoms";
import { StatusModal, StatusModalState } from "@organisms";
-import { ModalProvider, useModal } from "../../context/modal";
-import { userEvent, waitFor, within, screen } from "@storybook/testing-library";
-import { expect, jest } from "@storybook/jest";
+import { useModal } from "../../context/modal";
+import { callAll } from "@utils";
const meta = {
title: "Example/Modals/StatusModalWithLink",
component: StatusModal,
- decorators: [
- (Story) => (
-
-
-
- ),
- ],
} satisfies Meta;
export default meta;
const Template: StoryFn = (args) => {
- const { openModal, modal, closeModal } = useModal();
+ const { openModal, modal, modals, closeModal } = useModal();
const open = () => {
openModal({
@@ -48,12 +42,18 @@ const Template: StoryFn = (args) => {
- {modal?.component && (
+ {modals[modal.type]?.component && (
+ openModal({ type: "none", state: null })
+ )
+ : undefined
+ }
>
- {modal.component}
+ {modals[modal.type]?.component ?? <>>}
)}
>
diff --git a/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx b/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx
new file mode 100644
index 000000000..5820c9bb3
--- /dev/null
+++ b/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx
@@ -0,0 +1,56 @@
+import { Meta, StoryFn } from "@storybook/react";
+
+import { Modal } from "@atoms";
+import { StatusModal, VotingPowerModalState } from "@organisms";
+import { useModal } from "@context";
+import { callAll } from "@utils";
+
+const meta = {
+ title: "Example/Modals/VotingPowerModal",
+ component: StatusModal,
+} satisfies Meta;
+
+export default meta;
+
+const Template: StoryFn = (args) => {
+ const { openModal, modal, modals } = useModal();
+
+ const open = () => {
+ openModal({
+ type: "votingPower",
+ state: {
+ ...args,
+ },
+ });
+ };
+
+ return (
+ <>
+
+ {modals[modal.type]?.component && (
+
+ openModal({ type: "none", state: null })
+ )
+ : undefined
+ }
+ >
+ {modals[modal.type]?.component ?? <>>}
+
+ )}
+ >
+ );
+};
+
+export const Default = Template.bind({});
+Default.args = {
+ yesVotes: 1000000000000,
+ noVotes: 10000000000,
+ abstainVotes: 324000000,
+ vote: "yes",
+};