Skip to content

Commit 4c5cc3c

Browse files
committed
Create Form and TextInput components
1 parent c4fa343 commit 4c5cc3c

File tree

5 files changed

+142
-0
lines changed

5 files changed

+142
-0
lines changed

src/components/BogForm/BogForm.tsx

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Form } from 'radix-ui';
2+
import styles from './styles.module.css';
3+
import BogButton from '../BogButton/BogButton';
4+
import type { FormEventHandler } from 'react';
5+
6+
export interface BogFormProps {
7+
onSubmit?: FormEventHandler<HTMLFormElement>;
8+
submitLabel?: string;
9+
style?: React.CSSProperties;
10+
className?: string;
11+
children: React.ReactNode;
12+
}
13+
14+
export function BogForm({ onSubmit, submitLabel, style, className, children }: BogFormProps) {
15+
return (
16+
<Form.Root onSubmit={onSubmit} className={`${className} ${styles.root}`} style={style}>
17+
{children}
18+
<Form.Submit asChild>
19+
<BogButton type="submit">{submitLabel || 'Submit'}</BogButton>
20+
</Form.Submit>
21+
</Form.Root>
22+
);
23+
}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@layer base {
2+
.root {
3+
flex-direction: column;
4+
display: flex;
5+
row-gap: 1rem;
6+
padding: 1rem;
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { Form } from 'radix-ui';
2+
import styles from './styles.module.css';
3+
4+
export interface BogTextInputProps {
5+
multiline?: boolean;
6+
type?: 'text' | 'email' | 'password' | 'tel';
7+
name: string;
8+
label: string;
9+
placeholder?: string;
10+
required?: boolean;
11+
disabled?: boolean;
12+
13+
style?: React.CSSProperties;
14+
className?: string;
15+
}
16+
17+
export function BogTextInput({
18+
type = 'text',
19+
name,
20+
label,
21+
multiline = false,
22+
placeholder,
23+
required = true,
24+
disabled = false,
25+
style,
26+
className,
27+
}: BogTextInputProps) {
28+
return (
29+
<Form.Field name={name}>
30+
<div className="flex flex-row gap-x-2 text-paragraph-2">
31+
<Form.Label>{label}</Form.Label>
32+
<Form.Message match="valueMissing" className="text-status-red-text">
33+
Please enter a value for {label}
34+
</Form.Message>
35+
<Form.Message match="typeMismatch" className="text-status-red-text">
36+
Please provide a valid {label}
37+
</Form.Message>
38+
</div>
39+
<Form.Control asChild>
40+
{multiline ? (
41+
<textarea
42+
name={name}
43+
placeholder={placeholder}
44+
required={required}
45+
disabled={disabled}
46+
rows={4}
47+
className={`${styles.input} text-paragraph-2`}
48+
/>
49+
) : (
50+
<input
51+
name={name}
52+
type={type}
53+
placeholder={placeholder}
54+
required={required}
55+
disabled={disabled}
56+
className={`${styles.input} text-paragraph-2`}
57+
/>
58+
)}
59+
</Form.Control>
60+
</Form.Field>
61+
);
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
@layer base {
2+
.input {
3+
width: 100%;
4+
padding: 0.5rem;
5+
background-color: var(--color-solid-bg-sunken);
6+
border-radius: 0.5rem;
7+
border: 1px solid var(--color-grey-stroke-weak);
8+
&:hover {
9+
border-color: var(--color-brand-stroke-strong);
10+
}
11+
&:focus {
12+
outline: none;
13+
border-color: var(--color-brand-stroke-strong);
14+
}
15+
&:disabled {
16+
color: var(--color-grey-off-state);
17+
}
18+
}
19+
}

src/pages/index.tsx

+30
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import BogButton from '../components/BogButton/BogButton';
44
import { BogRadioItem } from '@/components/BogRadioItem/BogRadioItem';
55
import { useState } from 'react';
66
import BogCheckbox from '@/components/BogCheckbox/BogCheckbox';
7+
import { BogForm } from '@/components/BogForm/BogForm';
8+
import { BogTextInput } from '@/components/BogTextInput/BogTextInput';
79

810
export default function Home() {
911
const icons = [
@@ -206,6 +208,34 @@ export default function Home() {
206208
*/}
207209
<div className="flex flex-col items-center justify-between border-grey-stroke-strong border-solid rounded-sm border-2 mb-8">
208210
<h3 className="self-start ml-4 text-heading-3">Forms:</h3>
211+
<BogForm
212+
className="w-full px-4"
213+
onSubmit={(e) => {
214+
e.preventDefault();
215+
const data = Object.fromEntries(new FormData(e.currentTarget));
216+
console.log(data);
217+
}}
218+
>
219+
<BogTextInput name="name" label="Name" placeholder="Enter your name" />
220+
<BogTextInput name="email" label="Email" placeholder="Enter your email" />
221+
<BogTextInput
222+
name="password"
223+
label="Password"
224+
placeholder="Enter your password"
225+
type="password"
226+
required
227+
/>
228+
<BogTextInput name="phone" label="Phone" placeholder="Enter your phone number" type="tel" disabled />
229+
<BogTextInput multiline name="message" label="Message" placeholder="Enter your message" />
230+
<BogCheckbox label="Checkbox" name="checkbox" />
231+
{/* you have to include a `name` prop when using BogRadioGroup in a form! */}
232+
<BogRadioGroup name="radio">
233+
<BogRadioItem label="Option 1" value={'1'} />
234+
<BogRadioItem label="Option 2" value={'2'} />
235+
<BogRadioItem label="Option 3" value={'3'} />
236+
<BogRadioItem label="Option 4" value={'4'} />
237+
</BogRadioGroup>
238+
</BogForm>
209239
</div>
210240

211241
{/* Temp placeholder for style */}

0 commit comments

Comments
 (0)