Skip to content

Commit

Permalink
feat(forms): add ui component.
Browse files Browse the repository at this point in the history
  • Loading branch information
victorpavlov committed Mar 12, 2024
1 parent ae7ede5 commit f8d0a71
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 5 deletions.
8 changes: 4 additions & 4 deletions components/form-ctf/from-ctf-client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { ComponentFormFieldsFragment } from '#/gql/graphql';
import { formsMap } from '../forms/forms-mapping';
import { useComponentPreview } from '../hooks/use-component-preview';
import { FormContainer } from '../ui/form-container';

export const FormCtfClient: React.FC<{
data: ComponentFormFieldsFragment;
Expand All @@ -15,9 +16,8 @@ export const FormCtfClient: React.FC<{
// @ts-ignore
const Form = formsMap[data.form];

return <Form />;
return <FormContainer form={<Form />} headline={data.headline} addAttributes={addAttributes}/> ;
}


return <p>Form</p>;

return null;
};
1 change: 0 additions & 1 deletion components/forms/server-actions/subscription.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const onSubscribeFormAction = async (prevState: {
const data = Object.fromEntries(formData);
const parsed = subscriptionSchema.safeParse(data);
if (parsed.success) {
console.log(data);
return { message: "Subscribed successfully!", user: parsed.data }
} else {
return {
Expand Down
32 changes: 32 additions & 0 deletions components/ui/form-container/form-container.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Meta, StoryObj } from "@storybook/react";
import { SampleForm } from "../form/form.stories";
import { FormContainer } from "./form-container";

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
title: "Components/FormContainer",
component: FormContainer,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
layout: "fullscreen",
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
tags: ["autodocs"],
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {
headline: { control: "text" },
},
} satisfies Meta<typeof FormContainer>;

export default meta;
type Story = StoryObj<typeof meta>;
const defaultArgs = {
headline: "The from headline",
form: <SampleForm />
};
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Default: Story = {
args: {
...defaultArgs,
},
};
33 changes: 33 additions & 0 deletions components/ui/form-container/form-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ReactNode } from "react";

interface FormContainerProps {
headline?: string | null;
form?: ReactNode;
addAttributes?: (name: string) => object | null;
}

export function FormContainer(props: FormContainerProps) {
const {
headline,
form,
addAttributes = () => ({}), // Default to no-op.
} = props;

return (
<div className="container py-12">
<div className="max-w-screen-sm mx-auto">
{headline && (
<h2
{...addAttributes("headline")}
className={
"text-4xl font-bold mb-4"
}
>
{headline}
</h2>
)}
{form}
</div>
</div>
);
}
1 change: 1 addition & 0 deletions components/ui/form-container/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./form-container";
10 changes: 10 additions & 0 deletions components/ui/form/form.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Canvas, Meta } from '@storybook/blocks';

import * as FormStories from './form.stories';

<Meta of={FormStories} />

# Form

We are using a Form component from [Shadcn/UI/Form](https://ui.shadcn.com/docs/components/form). Please, follow the link above about the usage details.
<Canvas of={FormStories.SampleForm} />
43 changes: 43 additions & 0 deletions components/ui/form/form.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { Meta } from "@storybook/react";
import { useForm } from "react-hook-form";
import { Button } from "../button";
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "../form/form";
import { Input } from "../input";

export const SampleForm = () => {
const form = useForm();

return (
<Form {...form}>
<form action="">
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" {...field} />
</FormControl>
<FormDescription>This is your public display name.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
);
};

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
title: "UI/Form",
component: SampleForm,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
layout: "centered",
},
} satisfies Meta<typeof SampleForm>;

export default meta;
43 changes: 43 additions & 0 deletions components/ui/input/input.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { Meta, StoryObj } from "@storybook/react";
import { Label } from "../label";

import { Input } from "./input";

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
title: "UI/Input",
component: Input,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
layout: "centered",
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
tags: ["autodocs"],
} satisfies Meta<typeof Input>;

export default meta;
type Story = StoryObj<typeof meta>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Default: Story = {};
export const Email: Story = {
args: {
type: "email",
placeholder: "Email",
}
};
export const Disabled: Story = {
args: {
...Email.args,
disabled: true,
}
};

export const WithLabel: Story = {
render: () => (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="email">Email</Label>
<Input type="email" id="email" placeholder="Email" />
</div>
),
};
35 changes: 35 additions & 0 deletions components/ui/label/label.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Meta, StoryObj } from "@storybook/react";
import { Input } from "../input";

import { Label } from "./label";

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
title: "UI/Label",
component: Label,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
layout: "centered",
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
tags: ["autodocs"],
} satisfies Meta<typeof Label>;

export default meta;
type Story = StoryObj<typeof meta>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Default: Story = {
args: {
children: 'Label Text'
},
};

export const WithInput: Story = {
render: () => (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="email">Email</Label>
<Input type="email" id="email" placeholder="Email" />
</div>
),
};

0 comments on commit f8d0a71

Please sign in to comment.