From da41d6e667fe5ad388d76d0175430f3e268c3746 Mon Sep 17 00:00:00 2001 From: Luis Kellermann Date: Wed, 14 Aug 2024 03:17:22 +0000 Subject: [PATCH] feat: Add UI components for input, label, card, form, and form control. These components are necessary for implementing the User Registration feature. Implementations not finished --- frontend/components/ui/button/Button.vue | 29 +++++++++++++++ frontend/components/ui/button/index.ts | 37 +++++++++++++++++++ frontend/components/ui/card/Card.vue | 21 +++++++++++ frontend/components/ui/card/CardContent.vue | 14 +++++++ .../components/ui/card/CardDescription.vue | 14 +++++++ frontend/components/ui/card/CardFooter.vue | 14 +++++++ frontend/components/ui/card/CardHeader.vue | 14 +++++++ frontend/components/ui/card/CardTitle.vue | 14 +++++++ frontend/components/ui/card/index.ts | 6 +++ frontend/components/ui/form/FormControl.vue | 18 +++++++++ .../components/ui/form/FormDescription.vue | 20 ++++++++++ frontend/components/ui/form/FormItem.vue | 19 ++++++++++ frontend/components/ui/form/FormLabel.vue | 20 ++++++++++ frontend/components/ui/form/FormMessage.vue | 16 ++++++++ frontend/components/ui/form/index.ts | 11 ++++++ frontend/components/ui/form/injectionKeys.ts | 3 ++ frontend/components/ui/form/useFormField.ts | 36 ++++++++++++++++++ frontend/components/ui/input/Input.vue | 32 ++++++++++++++++ frontend/components/ui/input/index.ts | 1 + frontend/components/ui/label/Label.vue | 27 ++++++++++++++ frontend/components/ui/label/index.ts | 1 + 21 files changed, 367 insertions(+) create mode 100644 frontend/components/ui/button/Button.vue create mode 100644 frontend/components/ui/button/index.ts create mode 100644 frontend/components/ui/card/Card.vue create mode 100644 frontend/components/ui/card/CardContent.vue create mode 100644 frontend/components/ui/card/CardDescription.vue create mode 100644 frontend/components/ui/card/CardFooter.vue create mode 100644 frontend/components/ui/card/CardHeader.vue create mode 100644 frontend/components/ui/card/CardTitle.vue create mode 100644 frontend/components/ui/card/index.ts create mode 100644 frontend/components/ui/form/FormControl.vue create mode 100644 frontend/components/ui/form/FormDescription.vue create mode 100644 frontend/components/ui/form/FormItem.vue create mode 100644 frontend/components/ui/form/FormLabel.vue create mode 100644 frontend/components/ui/form/FormMessage.vue create mode 100644 frontend/components/ui/form/index.ts create mode 100644 frontend/components/ui/form/injectionKeys.ts create mode 100644 frontend/components/ui/form/useFormField.ts create mode 100644 frontend/components/ui/input/Input.vue create mode 100644 frontend/components/ui/input/index.ts create mode 100644 frontend/components/ui/label/Label.vue create mode 100644 frontend/components/ui/label/index.ts diff --git a/frontend/components/ui/button/Button.vue b/frontend/components/ui/button/Button.vue new file mode 100644 index 0000000..1094aa4 --- /dev/null +++ b/frontend/components/ui/button/Button.vue @@ -0,0 +1,29 @@ + + + diff --git a/frontend/components/ui/button/index.ts b/frontend/components/ui/button/index.ts new file mode 100644 index 0000000..c4cd814 --- /dev/null +++ b/frontend/components/ui/button/index.ts @@ -0,0 +1,37 @@ +import { type VariantProps, cva } from 'class-variance-authority'; + +export { default as Button } from './Button.vue'; + +export const buttonVariants = cva( + 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-heading font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-slate-950 disabled:pointer-events-none disabled:opacity-50 dark:focus-visible:ring-slate-300', + { + variants: { + variant: { + default: + 'bg-primaryColor text-white shadow hover:bg-primaryColor/90 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/90', + destructive: + 'bg-red-500 text-slate-50 shadow-sm hover:bg-red-500/90 dark:bg-red-900 dark:text-slate-50 dark:hover:bg-red-900/90', + outline: + 'border border-slate-200 bg-white shadow-sm hover:bg-slate-100 hover:text-slate-900 dark:border-slate-800 dark:bg-slate-950 dark:hover:bg-slate-800 dark:hover:text-slate-50', + secondary: + 'bg-slate-100 text-slate-900 shadow-sm hover:bg-slate-100/80 dark:bg-slate-800 dark:text-slate-50 dark:hover:bg-slate-800/80', + ghost: + 'hover:bg-slate-100 hover:text-slate-900 dark:hover:bg-slate-800 dark:hover:text-slate-50', + link: 'text-slate-900 underline-offset-4 hover:underline dark:text-slate-50' + }, + size: { + default: 'h-9 px-4 py-2', + xs: 'h-7 rounded-md px-2 text-xs', + sm: 'h-8 rounded-lg px-3 text-xs', + lg: 'h-10 rounded-lg px-8', + icon: 'h-9 w-9' + } + }, + defaultVariants: { + variant: 'default', + size: 'default' + } + } +); + +export type ButtonVariants = VariantProps; diff --git a/frontend/components/ui/card/Card.vue b/frontend/components/ui/card/Card.vue new file mode 100644 index 0000000..c20abf1 --- /dev/null +++ b/frontend/components/ui/card/Card.vue @@ -0,0 +1,21 @@ + + + diff --git a/frontend/components/ui/card/CardContent.vue b/frontend/components/ui/card/CardContent.vue new file mode 100644 index 0000000..8120c38 --- /dev/null +++ b/frontend/components/ui/card/CardContent.vue @@ -0,0 +1,14 @@ + + + diff --git a/frontend/components/ui/card/CardDescription.vue b/frontend/components/ui/card/CardDescription.vue new file mode 100644 index 0000000..62ee7eb --- /dev/null +++ b/frontend/components/ui/card/CardDescription.vue @@ -0,0 +1,14 @@ + + + diff --git a/frontend/components/ui/card/CardFooter.vue b/frontend/components/ui/card/CardFooter.vue new file mode 100644 index 0000000..2ccd68b --- /dev/null +++ b/frontend/components/ui/card/CardFooter.vue @@ -0,0 +1,14 @@ + + + diff --git a/frontend/components/ui/card/CardHeader.vue b/frontend/components/ui/card/CardHeader.vue new file mode 100644 index 0000000..b2eaf0c --- /dev/null +++ b/frontend/components/ui/card/CardHeader.vue @@ -0,0 +1,14 @@ + + + diff --git a/frontend/components/ui/card/CardTitle.vue b/frontend/components/ui/card/CardTitle.vue new file mode 100644 index 0000000..1a9bb61 --- /dev/null +++ b/frontend/components/ui/card/CardTitle.vue @@ -0,0 +1,14 @@ + + + diff --git a/frontend/components/ui/card/index.ts b/frontend/components/ui/card/index.ts new file mode 100644 index 0000000..872bc81 --- /dev/null +++ b/frontend/components/ui/card/index.ts @@ -0,0 +1,6 @@ +export { default as Card } from './Card.vue'; +export { default as CardHeader } from './CardHeader.vue'; +export { default as CardTitle } from './CardTitle.vue'; +export { default as CardDescription } from './CardDescription.vue'; +export { default as CardContent } from './CardContent.vue'; +export { default as CardFooter } from './CardFooter.vue'; diff --git a/frontend/components/ui/form/FormControl.vue b/frontend/components/ui/form/FormControl.vue new file mode 100644 index 0000000..f8ad425 --- /dev/null +++ b/frontend/components/ui/form/FormControl.vue @@ -0,0 +1,18 @@ + + + diff --git a/frontend/components/ui/form/FormDescription.vue b/frontend/components/ui/form/FormDescription.vue new file mode 100644 index 0000000..d7168df --- /dev/null +++ b/frontend/components/ui/form/FormDescription.vue @@ -0,0 +1,20 @@ + + + diff --git a/frontend/components/ui/form/FormItem.vue b/frontend/components/ui/form/FormItem.vue new file mode 100644 index 0000000..4c2cdcd --- /dev/null +++ b/frontend/components/ui/form/FormItem.vue @@ -0,0 +1,19 @@ + + + diff --git a/frontend/components/ui/form/FormLabel.vue b/frontend/components/ui/form/FormLabel.vue new file mode 100644 index 0000000..15fd6df --- /dev/null +++ b/frontend/components/ui/form/FormLabel.vue @@ -0,0 +1,20 @@ + + + diff --git a/frontend/components/ui/form/FormMessage.vue b/frontend/components/ui/form/FormMessage.vue new file mode 100644 index 0000000..9b0f484 --- /dev/null +++ b/frontend/components/ui/form/FormMessage.vue @@ -0,0 +1,16 @@ + + + diff --git a/frontend/components/ui/form/index.ts b/frontend/components/ui/form/index.ts new file mode 100644 index 0000000..940e5d4 --- /dev/null +++ b/frontend/components/ui/form/index.ts @@ -0,0 +1,11 @@ +export { + Form, + Field as FormField, + FieldArray as FormFieldArray +} from 'vee-validate'; +export { default as FormItem } from './FormItem.vue'; +export { default as FormLabel } from './FormLabel.vue'; +export { default as FormControl } from './FormControl.vue'; +export { default as FormMessage } from './FormMessage.vue'; +export { default as FormDescription } from './FormDescription.vue'; +export { FORM_ITEM_INJECTION_KEY } from './injectionKeys'; diff --git a/frontend/components/ui/form/injectionKeys.ts b/frontend/components/ui/form/injectionKeys.ts new file mode 100644 index 0000000..2338043 --- /dev/null +++ b/frontend/components/ui/form/injectionKeys.ts @@ -0,0 +1,3 @@ +import type { InjectionKey } from 'vue'; + +export const FORM_ITEM_INJECTION_KEY = Symbol() as InjectionKey; diff --git a/frontend/components/ui/form/useFormField.ts b/frontend/components/ui/form/useFormField.ts new file mode 100644 index 0000000..ac87fbe --- /dev/null +++ b/frontend/components/ui/form/useFormField.ts @@ -0,0 +1,36 @@ +import { + FieldContextKey, + useFieldError, + useIsFieldDirty, + useIsFieldTouched, + useIsFieldValid +} from 'vee-validate'; +import { inject } from 'vue'; +import { FORM_ITEM_INJECTION_KEY } from './injectionKeys'; + +export function useFormField() { + const fieldContext = inject(FieldContextKey); + const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY); + + if (!fieldContext) + throw new Error('useFormField should be used within '); + + const { name } = fieldContext; + const id = fieldItemContext; + + const fieldState = { + valid: useIsFieldValid(name), + isDirty: useIsFieldDirty(name), + isTouched: useIsFieldTouched(name), + error: useFieldError(name) + }; + + return { + id, + name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState + }; +} diff --git a/frontend/components/ui/input/Input.vue b/frontend/components/ui/input/Input.vue new file mode 100644 index 0000000..e38f950 --- /dev/null +++ b/frontend/components/ui/input/Input.vue @@ -0,0 +1,32 @@ + + + diff --git a/frontend/components/ui/input/index.ts b/frontend/components/ui/input/index.ts new file mode 100644 index 0000000..c5248c5 --- /dev/null +++ b/frontend/components/ui/input/index.ts @@ -0,0 +1 @@ +export { default as Input } from './Input.vue'; diff --git a/frontend/components/ui/label/Label.vue b/frontend/components/ui/label/Label.vue new file mode 100644 index 0000000..f04c37a --- /dev/null +++ b/frontend/components/ui/label/Label.vue @@ -0,0 +1,27 @@ + + + diff --git a/frontend/components/ui/label/index.ts b/frontend/components/ui/label/index.ts new file mode 100644 index 0000000..c98e59f --- /dev/null +++ b/frontend/components/ui/label/index.ts @@ -0,0 +1 @@ +export { default as Label } from './Label.vue';