Skip to content

Commit

Permalink
Merge pull request #3865 from bcgov/feat/2828
Browse files Browse the repository at this point in the history
feat(2828): add generic textarea components
  • Loading branch information
junminahn authored Sep 26, 2024
2 parents ce0eba2 + 08e9d02 commit 968c604
Show file tree
Hide file tree
Showing 17 changed files with 549 additions and 198 deletions.
2 changes: 1 addition & 1 deletion app/.knip.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://unpkg.com/knip@5/schema.json",
"entry": ["**/*.js", "**/*.ts", "**/*.tsx"],
"ignore": ["**/types/**/*.d.ts"],
"ignore": ["**/types/**/*.d.ts", ".next/**/*"],
"ignoreDependencies": [
"sharp",
"@testing-library/react",
Expand Down
78 changes: 78 additions & 0 deletions app/app/examples/ui/(components)/button/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
'use client';

import { Button } from '@mantine/core';
import { IconPhoto, IconDownload } from '@tabler/icons-react';
import classNames from 'classnames';
import createClientPage from '@/core/client-page';

const colors = ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark'];
const variants = ['filled', 'light', 'outline'];
const sizes = ['xl', 'compact-xl', 'lg', 'compact-lg', 'md', 'compact-md', 'sm', 'compact-sm', 'xs', 'compact-xs'];

const buttonPage = createClientPage({
roles: ['user'],
});
export default buttonPage(() => {
return (
<>
<h1 className="font-bold text-2xl mt-4 mb-5">Text Input</h1>
<div className={classNames('grid grid-cols-1 md:gap-4 md:py-2', `md:grid-cols-${colors.length}`)}>
{colors.map((color) => {
return (
<div className="col-span-1" key={color}>
{variants.map((variant) => {
return sizes.map((size) => {
return (
<div className="mb-3" key={color + variant + size}>
<div className="text-gray-800 text-sm font-bold">
{color} - {variant} - {size}
</div>
<Button color={color} variant={variant} size={size}>
{color}
</Button>
</div>
);
});
})}

<div className="mb-3">
<div className="text-gray-800 text-sm font-bold">{color} - full width</div>
<Button color={color} variant={variants[0]} fullWidth>
{color}
</Button>
</div>

<div className="mb-3">
<div className="text-gray-800 text-sm font-bold">{color} - disabled</div>
<Button color={color} variant={variants[0]} disabled>
{color}
</Button>
</div>

<div className="mb-3">
<div className="text-gray-800 text-sm font-bold">{color} - loading</div>
<Button color={color} variant={variants[0]} loading>
{color}
</Button>
</div>

<div className="mb-3">
<div className="text-gray-800 text-sm font-bold">{color} - left icon</div>
<Button color={color} variant={variants[0]} leftSection={<IconPhoto size={14} />}>
{color}
</Button>
</div>

<div className="mb-3">
<div className="text-gray-800 text-sm font-bold">{color} - right icon</div>
<Button color={color} variant={variants[0]} rightSection={<IconDownload size={14} />}>
{color}
</Button>
</div>
</div>
);
})}
</div>
</>
);
});
17 changes: 17 additions & 0 deletions app/app/examples/ui/(components)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client';

import Link from 'next/link';

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="">
<Link
href="/examples/ui"
className="text-blue-600 underline visited:text-purple-600 font-bold text-lg transition duration-200 ease-in-out"
>
Components
</Link>
{children}
</div>
);
}
26 changes: 26 additions & 0 deletions app/app/examples/ui/(components)/modal/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use client';

import { Button } from '@mantine/core';
import createClientPage from '@/core/client-page';
import { openTestModal } from './testModal';

const modalPage = createClientPage({});
export default modalPage(() => {
return (
<>
<h1 className="font-bold text-2xl mt-4 mb-5">Textarea</h1>
<Button
onClick={async () => {
const result = await openTestModal<{ value: number }>(
{ name: 'Platform Service Team' },
{ snapshot: { value: 1000 } },
);

console.log(result);
}}
>
Open Modal
</Button>
</>
);
});
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ export default Page(() => {
});

return (
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(console.log)} autoComplete="off">
<HookFormMultiSelect name="fruits" data={['apple', 'banana', 'avocado', 'grape', 'orange', 'raspberry']} />
<Button variant="success" type="submit" className="mt-1">
Submit
</Button>
</form>
</FormProvider>
<>
<h1 className="font-bold text-2xl mt-4 mb-5">Textarea</h1>
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(console.log)} autoComplete="off">
<HookFormMultiSelect name="fruits" data={['apple', 'banana', 'avocado', 'grape', 'orange', 'raspberry']} />
<Button variant="success" type="submit" className="mt-1">
Submit
</Button>
</form>
</FormProvider>
</>
);
});
File renamed without changes.
75 changes: 75 additions & 0 deletions app/app/examples/ui/(components)/text-input/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use client';

import { zodResolver } from '@hookform/resolvers/zod';
import { Button } from '@mantine/core';
import { FormProvider, useForm } from 'react-hook-form';
import { z } from 'zod';
import HookFormTextInput from '@/components/generic/input/HookFormTextInput';
import createClientPage from '@/core/client-page';
import { processNumber } from '@/utils/zod';

const validationSchema = z.object({
firstName: z.string().min(1).max(100),
lastName: z.string().min(1).max(100),
address: z.string().min(1).max(100),
age: z.preprocess((v) => processNumber(v), z.number().min(20)),
height: z.preprocess((v) => processNumber(v), z.number().min(100)),
});

const Page = createClientPage({
roles: ['user'],
});
export default Page(() => {
const methods = useForm({
resolver: zodResolver(validationSchema),
defaultValues: {},
});

return (
<>
<h1 className="font-bold text-2xl mt-4 mb-5">Text Input</h1>
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(console.log)} autoComplete="off">
<div className="grid grid-cols-1 md:grid-cols-3 md:gap-4 md:py-2">
<HookFormTextInput
label="First Name"
name="firstName"
placeholder="Enter first name..."
required
classNames={{ wrapper: 'col-span-1' }}
/>
<HookFormTextInput
label="Last Name"
name="lastName"
placeholder="Enter last name..."
required
classNames={{ wrapper: 'col-span-1' }}
/>
<HookFormTextInput
label="Address"
name="address"
placeholder="Enter address..."
classNames={{ wrapper: 'col-span-1' }}
/>
<HookFormTextInput
name="age"
type="number"
placeholder="Enter age..."
classNames={{ wrapper: 'col-span-1' }}
/>
<HookFormTextInput
name="height"
placeholder="Enter height..."
disabled
classNames={{ wrapper: 'col-span-1' }}
/>
</div>

<Button variant="success" type="submit" className="mt-1">
Submit
</Button>
</form>
</FormProvider>
</>
);
});
66 changes: 66 additions & 0 deletions app/app/examples/ui/(components)/textarea/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use client';

import { zodResolver } from '@hookform/resolvers/zod';
import { Button } from '@mantine/core';
import { FormProvider, useForm } from 'react-hook-form';
import { z } from 'zod';
import HookFormTextarea from '@/components/generic/input/HookFormTextarea';
import createClientPage from '@/core/client-page';

const validationSchema = z.object({
name: z.string().min(1).max(100),
sentence: z.string().min(1).max(100),
address: z.string().optional(),
});

const Page = createClientPage({
roles: ['user'],
});
export default Page(() => {
const methods = useForm({
resolver: zodResolver(validationSchema),
defaultValues: {
sentence:
'On a bright and sunny afternoon, the children gathered in the park, their laughter echoing through the air as they played games, chased butterflies, and shared stories under the shade of the old oak tree, creating memories that would last a lifetime.',
},
});

return (
<>
<h1 className="font-bold text-2xl mt-4 mb-5">Textarea</h1>
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(console.log)} autoComplete="off">
<div className="grid grid-cols-1 md:grid-cols-3 md:gap-4 md:py-2">
<HookFormTextarea
label="Name"
name="name"
placeholder="Enter name..."
required
classNames={{ wrapper: 'col-span-1' }}
/>
<HookFormTextarea
label="Sentence"
name="sentence"
placeholder="Enter sentence..."
required
disabled
copyable
classNames={{ wrapper: 'col-span-1' }}
/>
<HookFormTextarea
name="address"
placeholder="Enter address..."
copyable
classNames={{ wrapper: 'col-span-1' }}
rows={10}
/>
</div>

<Button variant="success" type="submit" className="mt-1">
Submit
</Button>
</form>
</FormProvider>
</>
);
});
75 changes: 0 additions & 75 deletions app/app/examples/ui/button/page.tsx

This file was deleted.

Loading

0 comments on commit 968c604

Please sign in to comment.