From 9e421058cb8537aa69ad54ce62a1102750e25646 Mon Sep 17 00:00:00 2001 From: PabloLec Date: Wed, 8 May 2024 18:44:36 +0200 Subject: [PATCH] Add shadcn Form, Input and Select --- test-frontend/package.json | 6 ++- test-frontend/pnpm-lock.yaml | 50 +++++++++++++++++ .../src/components/ui/form/FormControl.vue | 16 ++++++ .../components/ui/form/FormDescription.vue | 20 +++++++ .../src/components/ui/form/FormItem.vue | 25 +++++++++ .../src/components/ui/form/FormLabel.vue | 23 ++++++++ .../src/components/ui/form/FormMessage.vue | 16 ++++++ test-frontend/src/components/ui/form/index.ts | 6 +++ .../src/components/ui/form/useFormField.ts | 30 +++++++++++ .../src/components/ui/input/Input.vue | 24 +++++++++ .../src/components/ui/input/index.ts | 1 + .../src/components/ui/label/Label.vue | 27 ++++++++++ .../src/components/ui/label/index.ts | 1 + .../src/components/ui/select/Select.vue | 15 ++++++ .../components/ui/select/SelectContent.vue | 53 +++++++++++++++++++ .../src/components/ui/select/SelectGroup.vue | 19 +++++++ .../src/components/ui/select/SelectItem.vue | 44 +++++++++++++++ .../components/ui/select/SelectItemText.vue | 11 ++++ .../src/components/ui/select/SelectLabel.vue | 13 +++++ .../ui/select/SelectScrollDownButton.vue | 24 +++++++++ .../ui/select/SelectScrollUpButton.vue | 24 +++++++++ .../components/ui/select/SelectSeparator.vue | 17 ++++++ .../components/ui/select/SelectTrigger.vue | 31 +++++++++++ .../src/components/ui/select/SelectValue.vue | 11 ++++ .../src/components/ui/select/index.ts | 11 ++++ 25 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 test-frontend/src/components/ui/form/FormControl.vue create mode 100644 test-frontend/src/components/ui/form/FormDescription.vue create mode 100644 test-frontend/src/components/ui/form/FormItem.vue create mode 100644 test-frontend/src/components/ui/form/FormLabel.vue create mode 100644 test-frontend/src/components/ui/form/FormMessage.vue create mode 100644 test-frontend/src/components/ui/form/index.ts create mode 100644 test-frontend/src/components/ui/form/useFormField.ts create mode 100644 test-frontend/src/components/ui/input/Input.vue create mode 100644 test-frontend/src/components/ui/input/index.ts create mode 100644 test-frontend/src/components/ui/label/Label.vue create mode 100644 test-frontend/src/components/ui/label/index.ts create mode 100644 test-frontend/src/components/ui/select/Select.vue create mode 100644 test-frontend/src/components/ui/select/SelectContent.vue create mode 100644 test-frontend/src/components/ui/select/SelectGroup.vue create mode 100644 test-frontend/src/components/ui/select/SelectItem.vue create mode 100644 test-frontend/src/components/ui/select/SelectItemText.vue create mode 100644 test-frontend/src/components/ui/select/SelectLabel.vue create mode 100644 test-frontend/src/components/ui/select/SelectScrollDownButton.vue create mode 100644 test-frontend/src/components/ui/select/SelectScrollUpButton.vue create mode 100644 test-frontend/src/components/ui/select/SelectSeparator.vue create mode 100644 test-frontend/src/components/ui/select/SelectTrigger.vue create mode 100644 test-frontend/src/components/ui/select/SelectValue.vue create mode 100644 test-frontend/src/components/ui/select/index.ts diff --git a/test-frontend/package.json b/test-frontend/package.json index 375a91e..dbb8259 100644 --- a/test-frontend/package.json +++ b/test-frontend/package.json @@ -10,6 +10,8 @@ }, "dependencies": { "@tanstack/vue-table": "^8.16.0", + "@vee-validate/zod": "^4.12.7", + "@vueuse/core": "^10.9.0", "axios": "^1.6.8", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", @@ -17,7 +19,9 @@ "radix-vue": "^1.7.4", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", - "vue": "^3.4.21" + "vee-validate": "^4.12.7", + "vue": "^3.4.21", + "zod": "^3.23.7" }, "devDependencies": { "@types/node": "^20.12.11", diff --git a/test-frontend/pnpm-lock.yaml b/test-frontend/pnpm-lock.yaml index fee62b3..31e048c 100644 --- a/test-frontend/pnpm-lock.yaml +++ b/test-frontend/pnpm-lock.yaml @@ -11,6 +11,12 @@ importers: '@tanstack/vue-table': specifier: ^8.16.0 version: 8.16.0(vue@3.4.27(typescript@5.4.5)) + '@vee-validate/zod': + specifier: ^4.12.7 + version: 4.12.7(vue@3.4.27(typescript@5.4.5)) + '@vueuse/core': + specifier: ^10.9.0 + version: 10.9.0(vue@3.4.27(typescript@5.4.5)) axios: specifier: ^1.6.8 version: 1.6.8 @@ -32,9 +38,15 @@ importers: tailwindcss-animate: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.3) + vee-validate: + specifier: ^4.12.7 + version: 4.12.7(vue@3.4.27(typescript@5.4.5)) vue: specifier: ^3.4.21 version: 3.4.27(typescript@5.4.5) + zod: + specifier: ^3.23.7 + version: 3.23.7 devDependencies: '@types/node': specifier: ^20.12.11 @@ -386,6 +398,9 @@ packages: '@types/web-bluetooth@0.0.20': resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + '@vee-validate/zod@4.12.7': + resolution: {integrity: sha512-4VPly2tu9xpPP1onmDBOQPKAyivJ6j+1JF5YAXAf2ofoxfPAW2y8mBwe0zsKE1TAI8xyT9nkb2oWNzX1HrlPVw==} + '@vitejs/plugin-vue@5.0.4': resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -414,6 +429,9 @@ packages: '@vue/compiler-ssr@3.4.27': resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + '@vue/devtools-api@6.6.1': + resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==} + '@vue/language-core@2.0.16': resolution: {integrity: sha512-Bc2sexRH99pznOph8mLw2BlRZ9edm7tW51kcBXgx8adAoOcZUWJj3UNSsdQ6H9Y8meGz7BoazVrVo/jUukIsPw==} peerDependencies: @@ -972,6 +990,10 @@ packages: tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + type-fest@4.18.2: + resolution: {integrity: sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==} + engines: {node: '>=16'} + typescript@5.4.5: resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} engines: {node: '>=14.17'} @@ -989,6 +1011,11 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + vee-validate@4.12.7: + resolution: {integrity: sha512-1BGql4XNu/3TqHFjBLV6OrZ4fRteHXxRc9tLF5Q40IgIo1cwYEyaccC1AL3tdFUr2E3JsYhXbiEExoUSy4C9nA==} + peerDependencies: + vue: ^3.4.26 + vite@5.2.11: resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1063,6 +1090,9 @@ packages: engines: {node: '>= 14'} hasBin: true + zod@3.23.7: + resolution: {integrity: sha512-NBeIoqbtOiUMomACV/y+V3Qfs9+Okr18vR5c/5pHClPpufWOrsx8TENboDPe265lFdfewX2yBtNTLPvnmCxwog==} + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -1293,6 +1323,14 @@ snapshots: '@types/web-bluetooth@0.0.20': {} + '@vee-validate/zod@4.12.7(vue@3.4.27(typescript@5.4.5))': + dependencies: + type-fest: 4.18.2 + vee-validate: 4.12.7(vue@3.4.27(typescript@5.4.5)) + zod: 3.23.7 + transitivePeerDependencies: + - vue + '@vitejs/plugin-vue@5.0.4(vite@5.2.11(@types/node@20.12.11))(vue@3.4.27(typescript@5.4.5))': dependencies: vite: 5.2.11(@types/node@20.12.11) @@ -1341,6 +1379,8 @@ snapshots: '@vue/compiler-dom': 3.4.27 '@vue/shared': 3.4.27 + '@vue/devtools-api@6.6.1': {} + '@vue/language-core@2.0.16(typescript@5.4.5)': dependencies: '@volar/language-core': 2.2.1 @@ -1917,6 +1957,8 @@ snapshots: tslib@2.6.2: {} + type-fest@4.18.2: {} + typescript@5.4.5: {} undici-types@5.26.5: {} @@ -1929,6 +1971,12 @@ snapshots: util-deprecate@1.0.2: {} + vee-validate@4.12.7(vue@3.4.27(typescript@5.4.5)): + dependencies: + '@vue/devtools-api': 6.6.1 + type-fest: 4.18.2 + vue: 3.4.27(typescript@5.4.5) + vite@5.2.11(@types/node@20.12.11): dependencies: esbuild: 0.20.2 @@ -1981,3 +2029,5 @@ snapshots: strip-ansi: 7.1.0 yaml@2.4.2: {} + + zod@3.23.7: {} diff --git a/test-frontend/src/components/ui/form/FormControl.vue b/test-frontend/src/components/ui/form/FormControl.vue new file mode 100644 index 0000000..8459cab --- /dev/null +++ b/test-frontend/src/components/ui/form/FormControl.vue @@ -0,0 +1,16 @@ + + + diff --git a/test-frontend/src/components/ui/form/FormDescription.vue b/test-frontend/src/components/ui/form/FormDescription.vue new file mode 100644 index 0000000..6085f76 --- /dev/null +++ b/test-frontend/src/components/ui/form/FormDescription.vue @@ -0,0 +1,20 @@ + + + diff --git a/test-frontend/src/components/ui/form/FormItem.vue b/test-frontend/src/components/ui/form/FormItem.vue new file mode 100644 index 0000000..ad120be --- /dev/null +++ b/test-frontend/src/components/ui/form/FormItem.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/test-frontend/src/components/ui/form/FormLabel.vue b/test-frontend/src/components/ui/form/FormLabel.vue new file mode 100644 index 0000000..73cf45b --- /dev/null +++ b/test-frontend/src/components/ui/form/FormLabel.vue @@ -0,0 +1,23 @@ + + + diff --git a/test-frontend/src/components/ui/form/FormMessage.vue b/test-frontend/src/components/ui/form/FormMessage.vue new file mode 100644 index 0000000..308755e --- /dev/null +++ b/test-frontend/src/components/ui/form/FormMessage.vue @@ -0,0 +1,16 @@ + + + diff --git a/test-frontend/src/components/ui/form/index.ts b/test-frontend/src/components/ui/form/index.ts new file mode 100644 index 0000000..30a30a6 --- /dev/null +++ b/test-frontend/src/components/ui/form/index.ts @@ -0,0 +1,6 @@ +export { Form, Field as FormField } 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' diff --git a/test-frontend/src/components/ui/form/useFormField.ts b/test-frontend/src/components/ui/form/useFormField.ts new file mode 100644 index 0000000..73eeee3 --- /dev/null +++ b/test-frontend/src/components/ui/form/useFormField.ts @@ -0,0 +1,30 @@ +import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate' +import { inject } from 'vue' +import { FORM_ITEM_INJECTION_KEY } from './FormItem.vue' + +export function useFormField() { + const fieldContext = inject(FieldContextKey) + const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY) + + const fieldState = { + valid: useIsFieldValid(), + isDirty: useIsFieldDirty(), + isTouched: useIsFieldTouched(), + error: useFieldError(), + } + + if (!fieldContext) + throw new Error('useFormField should be used within ') + + const { name } = fieldContext + const id = fieldItemContext + + return { + id, + name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + } +} diff --git a/test-frontend/src/components/ui/input/Input.vue b/test-frontend/src/components/ui/input/Input.vue new file mode 100644 index 0000000..39c9cee --- /dev/null +++ b/test-frontend/src/components/ui/input/Input.vue @@ -0,0 +1,24 @@ + + + diff --git a/test-frontend/src/components/ui/input/index.ts b/test-frontend/src/components/ui/input/index.ts new file mode 100644 index 0000000..a691dd6 --- /dev/null +++ b/test-frontend/src/components/ui/input/index.ts @@ -0,0 +1 @@ +export { default as Input } from './Input.vue' diff --git a/test-frontend/src/components/ui/label/Label.vue b/test-frontend/src/components/ui/label/Label.vue new file mode 100644 index 0000000..8fba8db --- /dev/null +++ b/test-frontend/src/components/ui/label/Label.vue @@ -0,0 +1,27 @@ + + + diff --git a/test-frontend/src/components/ui/label/index.ts b/test-frontend/src/components/ui/label/index.ts new file mode 100644 index 0000000..572c2f0 --- /dev/null +++ b/test-frontend/src/components/ui/label/index.ts @@ -0,0 +1 @@ +export { default as Label } from './Label.vue' diff --git a/test-frontend/src/components/ui/select/Select.vue b/test-frontend/src/components/ui/select/Select.vue new file mode 100644 index 0000000..adc42fd --- /dev/null +++ b/test-frontend/src/components/ui/select/Select.vue @@ -0,0 +1,15 @@ + + + diff --git a/test-frontend/src/components/ui/select/SelectContent.vue b/test-frontend/src/components/ui/select/SelectContent.vue new file mode 100644 index 0000000..4fe234b --- /dev/null +++ b/test-frontend/src/components/ui/select/SelectContent.vue @@ -0,0 +1,53 @@ + + + diff --git a/test-frontend/src/components/ui/select/SelectGroup.vue b/test-frontend/src/components/ui/select/SelectGroup.vue new file mode 100644 index 0000000..407d8ad --- /dev/null +++ b/test-frontend/src/components/ui/select/SelectGroup.vue @@ -0,0 +1,19 @@ + + + diff --git a/test-frontend/src/components/ui/select/SelectItem.vue b/test-frontend/src/components/ui/select/SelectItem.vue new file mode 100644 index 0000000..b102a81 --- /dev/null +++ b/test-frontend/src/components/ui/select/SelectItem.vue @@ -0,0 +1,44 @@ + + + diff --git a/test-frontend/src/components/ui/select/SelectItemText.vue b/test-frontend/src/components/ui/select/SelectItemText.vue new file mode 100644 index 0000000..a0bb5c2 --- /dev/null +++ b/test-frontend/src/components/ui/select/SelectItemText.vue @@ -0,0 +1,11 @@ + + + diff --git a/test-frontend/src/components/ui/select/SelectLabel.vue b/test-frontend/src/components/ui/select/SelectLabel.vue new file mode 100644 index 0000000..3d45cdb --- /dev/null +++ b/test-frontend/src/components/ui/select/SelectLabel.vue @@ -0,0 +1,13 @@ + + + diff --git a/test-frontend/src/components/ui/select/SelectScrollDownButton.vue b/test-frontend/src/components/ui/select/SelectScrollDownButton.vue new file mode 100644 index 0000000..54b6c6a --- /dev/null +++ b/test-frontend/src/components/ui/select/SelectScrollDownButton.vue @@ -0,0 +1,24 @@ + + + diff --git a/test-frontend/src/components/ui/select/SelectScrollUpButton.vue b/test-frontend/src/components/ui/select/SelectScrollUpButton.vue new file mode 100644 index 0000000..5535f1c --- /dev/null +++ b/test-frontend/src/components/ui/select/SelectScrollUpButton.vue @@ -0,0 +1,24 @@ + + + diff --git a/test-frontend/src/components/ui/select/SelectSeparator.vue b/test-frontend/src/components/ui/select/SelectSeparator.vue new file mode 100644 index 0000000..5ae593d --- /dev/null +++ b/test-frontend/src/components/ui/select/SelectSeparator.vue @@ -0,0 +1,17 @@ + + + diff --git a/test-frontend/src/components/ui/select/SelectTrigger.vue b/test-frontend/src/components/ui/select/SelectTrigger.vue new file mode 100644 index 0000000..cfac8eb --- /dev/null +++ b/test-frontend/src/components/ui/select/SelectTrigger.vue @@ -0,0 +1,31 @@ + + + diff --git a/test-frontend/src/components/ui/select/SelectValue.vue b/test-frontend/src/components/ui/select/SelectValue.vue new file mode 100644 index 0000000..4bc37dd --- /dev/null +++ b/test-frontend/src/components/ui/select/SelectValue.vue @@ -0,0 +1,11 @@ + + + diff --git a/test-frontend/src/components/ui/select/index.ts b/test-frontend/src/components/ui/select/index.ts new file mode 100644 index 0000000..b1d89ee --- /dev/null +++ b/test-frontend/src/components/ui/select/index.ts @@ -0,0 +1,11 @@ +export { default as Select } from './Select.vue' +export { default as SelectValue } from './SelectValue.vue' +export { default as SelectTrigger } from './SelectTrigger.vue' +export { default as SelectContent } from './SelectContent.vue' +export { default as SelectGroup } from './SelectGroup.vue' +export { default as SelectItem } from './SelectItem.vue' +export { default as SelectItemText } from './SelectItemText.vue' +export { default as SelectLabel } from './SelectLabel.vue' +export { default as SelectSeparator } from './SelectSeparator.vue' +export { default as SelectScrollUpButton } from './SelectScrollUpButton.vue' +export { default as SelectScrollDownButton } from './SelectScrollDownButton.vue'