@carlonicora/nextjs-jsonapi 1.24.1 → 1.24.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/{BlockNoteEditor-UCHRVVVZ.js → BlockNoteEditor-OFSTXGZX.js} +6 -6
  2. package/dist/{BlockNoteEditor-UCHRVVVZ.js.map → BlockNoteEditor-OFSTXGZX.js.map} +1 -1
  3. package/dist/{BlockNoteEditor-ZYZZ6B45.mjs → BlockNoteEditor-TJNLCNIP.mjs} +2 -2
  4. package/dist/billing/index.js +300 -303
  5. package/dist/billing/index.js.map +1 -1
  6. package/dist/billing/index.mjs +5 -8
  7. package/dist/billing/index.mjs.map +1 -1
  8. package/dist/{chunk-ILKUML3Z.js → chunk-EJALOG7L.js} +4002 -3923
  9. package/dist/chunk-EJALOG7L.js.map +1 -0
  10. package/dist/{chunk-CU4RXSNY.mjs → chunk-H5JZ5E7M.mjs} +4336 -4257
  11. package/dist/chunk-H5JZ5E7M.mjs.map +1 -0
  12. package/dist/client/index.js +2 -2
  13. package/dist/client/index.mjs +1 -1
  14. package/dist/components/index.d.mts +69 -34
  15. package/dist/components/index.d.ts +69 -34
  16. package/dist/components/index.js +20 -2
  17. package/dist/components/index.js.map +1 -1
  18. package/dist/components/index.mjs +35 -17
  19. package/dist/contexts/index.js +2 -2
  20. package/dist/contexts/index.mjs +1 -1
  21. package/dist/scripts/generate-web-module/templates/components/editor.template.js +11 -13
  22. package/dist/scripts/generate-web-module/templates/components/editor.template.js.map +1 -1
  23. package/dist/scripts/generate-web-module/templates/components/multi-selector.template.d.ts.map +1 -1
  24. package/dist/scripts/generate-web-module/templates/components/multi-selector.template.js +13 -26
  25. package/dist/scripts/generate-web-module/templates/components/multi-selector.template.js.map +1 -1
  26. package/dist/scripts/generate-web-module/templates/components/selector.template.d.ts.map +1 -1
  27. package/dist/scripts/generate-web-module/templates/components/selector.template.js +59 -76
  28. package/dist/scripts/generate-web-module/templates/components/selector.template.js.map +1 -1
  29. package/dist/scripts/generate-web-module/transformers/field-mapper.d.ts.map +1 -1
  30. package/dist/scripts/generate-web-module/transformers/field-mapper.js +10 -12
  31. package/dist/scripts/generate-web-module/transformers/field-mapper.js.map +1 -1
  32. package/package.json +2 -2
  33. package/scripts/generate-web-module/templates/components/editor.template.ts +11 -13
  34. package/scripts/generate-web-module/templates/components/multi-selector.template.ts +13 -26
  35. package/scripts/generate-web-module/templates/components/selector.template.ts +59 -76
  36. package/scripts/generate-web-module/transformers/field-mapper.ts +10 -12
  37. package/src/components/forms/FormCheckbox.tsx +18 -24
  38. package/src/components/forms/FormDate.tsx +103 -116
  39. package/src/components/forms/FormDateTime.tsx +122 -130
  40. package/src/components/forms/FormFieldWrapper.tsx +54 -0
  41. package/src/components/forms/FormInput.tsx +58 -46
  42. package/src/components/forms/FormPassword.tsx +17 -24
  43. package/src/components/forms/FormPlaceAutocomplete.tsx +50 -75
  44. package/src/components/forms/FormSelect.tsx +29 -35
  45. package/src/components/forms/FormSlider.tsx +23 -27
  46. package/src/components/forms/FormSwitch.tsx +12 -14
  47. package/src/components/forms/FormTextarea.tsx +12 -19
  48. package/src/components/forms/__tests__/FormInput.test.tsx +4 -2
  49. package/src/components/forms/index.ts +1 -1
  50. package/src/components/pages/PageContentContainer.tsx +2 -1
  51. package/src/features/billing/stripe-price/components/forms/PriceEditor.tsx +9 -13
  52. package/src/features/company/components/forms/CompanyConfigurationSecurityForm.tsx +19 -33
  53. package/src/features/feature/components/forms/FormFeatures.tsx +3 -4
  54. package/src/features/role/components/forms/FormRoles.tsx +40 -51
  55. package/src/features/user/components/forms/UserMultiSelect.tsx +12 -29
  56. package/src/features/user/components/forms/UserSelector.tsx +79 -91
  57. package/src/hooks/__tests__/useDataListRetriever.test.ts +10 -1
  58. package/src/shadcnui/index.ts +2 -0
  59. package/src/shadcnui/ui/field.tsx +3 -3
  60. package/src/shadcnui/ui/form.tsx +17 -134
  61. package/src/shadcnui/ui/input-group.tsx +4 -4
  62. package/src/shadcnui/ui/resizable.tsx +8 -8
  63. package/dist/chunk-CU4RXSNY.mjs.map +0 -1
  64. package/dist/chunk-ILKUML3Z.js.map +0 -1
  65. package/src/components/forms/FormContainerGeneric.tsx +0 -39
  66. /package/dist/{BlockNoteEditor-ZYZZ6B45.mjs.map → BlockNoteEditor-TJNLCNIP.mjs.map} +0 -0
@@ -1,13 +1,10 @@
1
1
  "use client";
2
2
 
3
3
  import { useTranslations } from "next-intl";
4
+ import { FormFieldWrapper } from "../../../../components/forms";
4
5
  import {
5
6
  Checkbox,
6
- FormControl,
7
- FormField,
8
- FormItem,
9
- FormLabel,
10
- FormMessage,
7
+ FieldLabel,
11
8
  Tooltip,
12
9
  TooltipContent,
13
10
  TooltipTrigger,
@@ -29,54 +26,46 @@ export function FormRoles({ form, id, name, roles }: FormRolesProps) {
29
26
 
30
27
  return (
31
28
  <div className="flex w-full flex-col">
32
- <FormField
33
- control={form.control}
34
- name={id}
35
- render={({ field }) => (
36
- <FormItem className={`${name ? "mb-5" : "mb-1"}`}>
37
- <FormControl>
38
- <div>
39
- <div className="text-sm font-semibold">{name}</div>
40
- {roles
41
- .filter((role: RoleInterface) => role.isSelectable)
42
- .sort((a: RoleInterface, b: RoleInterface) => a.name.localeCompare(b.name))
43
- .map((role: RoleInterface) => {
44
- if (role.requiredFeature && !hasAccesToFeature(role.requiredFeature.id)) return null;
29
+ <FormFieldWrapper form={form} name={id} label={name}>
30
+ {(field) => (
31
+ <div>
32
+ {roles
33
+ .filter((role: RoleInterface) => role.isSelectable)
34
+ .sort((a: RoleInterface, b: RoleInterface) => a.name.localeCompare(b.name))
35
+ .map((role: RoleInterface) => {
36
+ if (role.requiredFeature && !hasAccesToFeature(role.requiredFeature.id)) return null;
45
37
 
46
- return (
47
- <div key={role.id}>
48
- <Checkbox
49
- defaultChecked={(field.value as string[]).some((roleId: string) => roleId === role.id)}
50
- onCheckedChange={(checked) => {
51
- if (checked) {
52
- form.setValue(id, [...(field.value as string[]), role.id]);
53
- } else {
54
- form.setValue(
55
- id,
56
- (field.value as string[]).filter((roleId: string) => roleId !== role.id),
57
- );
58
- }
59
- }}
60
- />
61
- <Tooltip>
62
- <TooltipTrigger>
63
- <FormLabel className="ml-3 font-normal">
64
- {t(`foundations.role.roles`, { role: role.id.replaceAll(`-`, ``) })}
65
- </FormLabel>
66
- </TooltipTrigger>
67
- <TooltipContent>
68
- {t(`foundations.role.roles_descriptions`, { role: role.id.replaceAll(`-`, ``) })}
69
- </TooltipContent>
70
- </Tooltip>
71
- </div>
72
- );
73
- })}
74
- </div>
75
- </FormControl>
76
- <FormMessage />
77
- </FormItem>
38
+ return (
39
+ <div key={role.id}>
40
+ <Checkbox
41
+ defaultChecked={(field.value as string[]).some((roleId: string) => roleId === role.id)}
42
+ onCheckedChange={(checked) => {
43
+ if (checked) {
44
+ form.setValue(id, [...(field.value as string[]), role.id]);
45
+ } else {
46
+ form.setValue(
47
+ id,
48
+ (field.value as string[]).filter((roleId: string) => roleId !== role.id),
49
+ );
50
+ }
51
+ }}
52
+ />
53
+ <Tooltip>
54
+ <TooltipTrigger>
55
+ <FieldLabel className="ml-3 font-normal">
56
+ {t(`foundations.role.roles`, { role: role.id.replaceAll(`-`, ``) })}
57
+ </FieldLabel>
58
+ </TooltipTrigger>
59
+ <TooltipContent>
60
+ {t(`foundations.role.roles_descriptions`, { role: role.id.replaceAll(`-`, ``) })}
61
+ </TooltipContent>
62
+ </Tooltip>
63
+ </div>
64
+ );
65
+ })}
66
+ </div>
78
67
  )}
79
- />
68
+ </FormFieldWrapper>
80
69
  </div>
81
70
  );
82
71
  }
@@ -2,17 +2,13 @@
2
2
 
3
3
  import { useCallback, useEffect, useRef, useState } from "react";
4
4
  import { useWatch } from "react-hook-form";
5
+ import { FormFieldWrapper } from "../../../../components/forms";
5
6
  import { Modules } from "../../../../core";
6
7
  import { DataListRetriever, useDataListRetriever, useDebounce } from "../../../../hooks";
7
8
  import {
8
9
  Avatar,
9
10
  AvatarFallback,
10
11
  AvatarImage,
11
- FormControl,
12
- FormField,
13
- FormItem,
14
- FormLabel,
15
- FormMessage,
16
12
  MultiSelect,
17
13
  } from "../../../../shadcnui";
18
14
  import { useCurrentUserContext } from "../../contexts";
@@ -189,31 +185,18 @@ export function UserMultiSelect({
189
185
 
190
186
  return (
191
187
  <div className="flex w-full flex-col">
192
- <FormField
193
- control={form.control}
194
- name={id}
195
- render={({ field }) => (
196
- <FormItem className={`${label ? "mb-5" : "mb-1"}`}>
197
- {label && (
198
- <FormLabel className="flex items-center">
199
- {label}
200
- {isRequired && <span className="text-destructive ml-2 font-semibold">*</span>}
201
- </FormLabel>
202
- )}
203
- <FormControl>
204
- <MultiSelect
205
- options={userOptions}
206
- onValueChange={handleValueChange}
207
- defaultValue={selectedUserIds}
208
- placeholder={placeholder}
209
- maxCount={maxCount}
210
- animation={0}
211
- />
212
- </FormControl>
213
- <FormMessage />
214
- </FormItem>
188
+ <FormFieldWrapper form={form} name={id} label={label} isRequired={isRequired}>
189
+ {() => (
190
+ <MultiSelect
191
+ options={userOptions}
192
+ onValueChange={handleValueChange}
193
+ defaultValue={selectedUserIds}
194
+ placeholder={placeholder}
195
+ maxCount={maxCount}
196
+ animation={0}
197
+ />
215
198
  )}
216
- />
199
+ </FormFieldWrapper>
217
200
  </div>
218
201
  );
219
202
  }
@@ -5,6 +5,7 @@ import { useTranslations } from "next-intl";
5
5
  import { useCallback, useEffect, useRef, useState } from "react";
6
6
  import { Modules } from "../../../../core";
7
7
  import { DataListRetriever, useDataListRetriever, useDebounce } from "../../../../hooks";
8
+ import { FormFieldWrapper } from "../../../../components/forms";
8
9
  import {
9
10
  Avatar,
10
11
  AvatarFallback,
@@ -12,11 +13,6 @@ import {
12
13
  Command,
13
14
  CommandItem,
14
15
  CommandList,
15
- FormControl,
16
- FormField,
17
- FormItem,
18
- FormLabel,
19
- FormMessage,
20
16
  Input,
21
17
  Popover,
22
18
  PopoverContent,
@@ -92,99 +88,91 @@ export function UserSelector({ id, form, label, placeholder, onChange, isRequire
92
88
 
93
89
  return (
94
90
  <div className="flex w-full flex-col">
95
- <FormField
96
- control={form.control}
91
+ <FormFieldWrapper
92
+ form={form}
97
93
  name={id}
98
- render={({ field }) => (
99
- <FormItem className={`${label ? "mb-5" : "mb-1"}`}>
100
- {label && (
101
- <FormLabel className="flex items-center">
102
- {label}
103
- {isRequired && <span className="text-destructive ml-2 font-semibold">*</span>}
104
- </FormLabel>
105
- )}
106
- <FormControl>
107
- <Popover open={open} onOpenChange={setOpen} modal={true}>
108
- <div className="flex w-full flex-row items-center justify-between">
109
- <PopoverTrigger className="w-full">
110
- <div className="flex w-full flex-row items-center justify-start rounded-md">
111
- {field.value ? (
112
- <>
113
- <div className="flex w-full flex-row items-center justify-start rounded-md border p-2">
114
- <div className="*:ring-border *:ring-1">
115
- <Avatar className={`mr-2 h-6 w-6`}>
116
- <AvatarImage src={field.value?.avatar} />
117
- <AvatarFallback>
118
- {field.value?.name
119
- ? field.value?.name.split(" ").map((name: string) => name.charAt(0).toUpperCase())
120
- : "X"}
121
- </AvatarFallback>
122
- </Avatar>
123
- </div>
124
- <span className="">{field.value?.name ?? ""}</span>
125
- </div>
126
- </>
127
- ) : (
128
- <div className="text-muted-foreground mr-7 flex h-10 w-full flex-row items-center justify-start rounded-md border p-2 text-sm">
129
- {placeholder ?? t(`generic.search.placeholder`, { type: t(`types.users`, { count: 1 }) })}
94
+ label={label}
95
+ isRequired={isRequired}
96
+ >
97
+ {(field) => (
98
+ <Popover open={open} onOpenChange={setOpen} modal={true}>
99
+ <div className="flex w-full flex-row items-center justify-between">
100
+ <PopoverTrigger className="w-full">
101
+ <div className="flex w-full flex-row items-center justify-start rounded-md">
102
+ {field.value ? (
103
+ <>
104
+ <div className="flex w-full flex-row items-center justify-start rounded-md border p-2">
105
+ <div className="*:ring-border *:ring-1">
106
+ <Avatar className={`mr-2 h-6 w-6`}>
107
+ <AvatarImage src={field.value?.avatar} />
108
+ <AvatarFallback>
109
+ {field.value?.name
110
+ ? field.value?.name.split(" ").map((name: string) => name.charAt(0).toUpperCase())
111
+ : "X"}
112
+ </AvatarFallback>
113
+ </Avatar>
130
114
  </div>
131
- )}
115
+ <span className="">{field.value?.name ?? ""}</span>
116
+ </div>
117
+ </>
118
+ ) : (
119
+ <div className="text-muted-foreground mr-7 flex h-10 w-full flex-row items-center justify-start rounded-md border p-2 text-sm">
120
+ {placeholder ?? t(`generic.search.placeholder`, { type: t(`types.users`, { count: 1 }) })}
132
121
  </div>
133
- </PopoverTrigger>
134
- {field.value && (
135
- <CircleX
136
- className="text-muted hover:text-destructive ml-2 h-6 w-6 cursor-pointer"
137
- onClick={() => setUser()}
122
+ )}
123
+ </div>
124
+ </PopoverTrigger>
125
+ {field.value && (
126
+ <CircleX
127
+ className="text-muted hover:text-destructive ml-2 h-6 w-6 cursor-pointer"
128
+ onClick={() => setUser()}
129
+ />
130
+ )}
131
+ </div>
132
+ <PopoverContent>
133
+ <Command shouldFilter={false}>
134
+ <div className="relative mb-2 w-full">
135
+ <SearchIcon className="text-muted-foreground absolute top-2.5 left-2.5 h-4 w-4" />
136
+ <Input
137
+ placeholder={t(`generic.search.placeholder`, { type: t(`types.users`, { count: 1 }) })}
138
+ type="text"
139
+ className="w-full pr-8 pl-8"
140
+ onChange={(e) => setSearchTerm(e.target.value)}
141
+ value={searchTerm}
142
+ />
143
+ {isSearching ? (
144
+ <RefreshCwIcon className="text-muted-foreground absolute top-2.5 right-2.5 h-4 w-4 animate-spin" />
145
+ ) : searchTermRef.current ? (
146
+ <XIcon
147
+ className={`absolute top-2.5 right-2.5 h-4 w-4 ${searchTermRef.current ? "cursor-pointer" : "text-muted-foreground"}`}
148
+ onClick={() => {
149
+ setSearchTerm("");
150
+ search("");
151
+ }}
138
152
  />
153
+ ) : (
154
+ <></>
139
155
  )}
140
156
  </div>
141
- <PopoverContent>
142
- <Command shouldFilter={false}>
143
- <div className="relative mb-2 w-full">
144
- <SearchIcon className="text-muted-foreground absolute top-2.5 left-2.5 h-4 w-4" />
145
- <Input
146
- placeholder={t(`generic.search.placeholder`, { type: t(`types.users`, { count: 1 }) })}
147
- type="text"
148
- className="w-full pr-8 pl-8"
149
- onChange={(e) => setSearchTerm(e.target.value)}
150
- value={searchTerm}
151
- />
152
- {isSearching ? (
153
- <RefreshCwIcon className="text-muted-foreground absolute top-2.5 right-2.5 h-4 w-4 animate-spin" />
154
- ) : searchTermRef.current ? (
155
- <XIcon
156
- className={`absolute top-2.5 right-2.5 h-4 w-4 ${searchTermRef.current ? "cursor-pointer" : "text-muted-foreground"}`}
157
- onClick={() => {
158
- setSearchTerm("");
159
- search("");
160
- }}
161
- />
162
- ) : (
163
- <></>
164
- )}
165
- </div>
166
- <CommandList>
167
- {data.data &&
168
- data.data.length > 0 &&
169
- (data.data as UserInterface[]).map((user: UserInterface) => (
170
- <CommandItem
171
- className="cursor-pointer hover:bg-muted data-selected:hover:bg-muted bg-transparent data-selected:bg-transparent"
172
- key={user.id}
173
- onSelect={() => setUser(user)}
174
- >
175
- <UserAvatar user={user} className={`mr-2 h-4 w-4`} />
176
- <span className="">{user.name}</span>
177
- </CommandItem>
178
- ))}
179
- </CommandList>
180
- </Command>
181
- </PopoverContent>
182
- </Popover>
183
- </FormControl>
184
- <FormMessage />
185
- </FormItem>
157
+ <CommandList>
158
+ {data.data &&
159
+ data.data.length > 0 &&
160
+ (data.data as UserInterface[]).map((user: UserInterface) => (
161
+ <CommandItem
162
+ className="cursor-pointer hover:bg-muted data-selected:hover:bg-muted bg-transparent data-selected:bg-transparent"
163
+ key={user.id}
164
+ onSelect={() => setUser(user)}
165
+ >
166
+ <UserAvatar user={user} className={`mr-2 h-4 w-4`} />
167
+ <span className="">{user.name}</span>
168
+ </CommandItem>
169
+ ))}
170
+ </CommandList>
171
+ </Command>
172
+ </PopoverContent>
173
+ </Popover>
186
174
  )}
187
- />
175
+ </FormFieldWrapper>
188
176
  </div>
189
177
  );
190
178
  }
@@ -25,7 +25,11 @@ describe("useDataListRetriever", () => {
25
25
  })
26
26
  );
27
27
 
28
- // Initially should not be loaded
28
+ // Wait for async operations to settle
29
+ await waitFor(() => {
30
+ expect(result.current.isLoaded).toBe(true);
31
+ });
32
+
29
33
  expect(result.current.ready).toBe(true);
30
34
  expect(result.current.isSearch).toBe(false);
31
35
  });
@@ -194,6 +198,11 @@ describe("useDataListRetriever", () => {
194
198
  result.current.setReady(true);
195
199
  });
196
200
 
201
+ // Wait for async operations triggered by setReady(true) to settle
202
+ await waitFor(() => {
203
+ expect(result.current.isLoaded).toBe(true);
204
+ });
205
+
197
206
  expect(result.current.ready).toBe(true);
198
207
  });
199
208
  });
@@ -19,9 +19,11 @@ export * from "./ui/context-menu";
19
19
  export * from "./ui/dialog";
20
20
  export * from "./ui/drawer";
21
21
  export * from "./ui/dropdown-menu";
22
+ export * from "./ui/field";
22
23
  export * from "./ui/form";
23
24
  export * from "./ui/hover-card";
24
25
  export * from "./ui/input";
26
+ export * from "./ui/input-group";
25
27
  export * from "./ui/input-otp";
26
28
  export * from "./ui/label";
27
29
  export * from "./ui/navigation-menu";
@@ -3,9 +3,9 @@
3
3
  import { useMemo } from "react"
4
4
  import { cva, type VariantProps } from "class-variance-authority"
5
5
 
6
- import { cn } from "@/lib/utils"
7
- import { Label } from "@/components/ui/label"
8
- import { Separator } from "@/components/ui/separator"
6
+ import { cn } from "../../utils/cn"
7
+ import { Label } from "./label"
8
+ import { Separator } from "./separator"
9
9
 
10
10
  function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
11
11
  return (
@@ -1,138 +1,21 @@
1
1
  "use client";
2
2
 
3
- import * as LabelPrimitive from "@radix-ui/react-label";
4
- import { Slot } from "@radix-ui/react-slot";
5
- import * as React from "react";
6
- import { Controller, ControllerProps, FieldPath, FieldValues, FormProvider, useFormContext } from "react-hook-form";
7
-
8
- import { Label } from "./label";
9
- import { cn } from "../../utils/cn";
10
-
3
+ import { FormProvider } from "react-hook-form";
4
+
5
+ /**
6
+ * Form component is a wrapper around react-hook-form's FormProvider.
7
+ * Use this to wrap your form and spread the form object into it.
8
+ *
9
+ * @example
10
+ * const form = useForm<FormValues>();
11
+ * return (
12
+ * <Form {...form}>
13
+ * <form onSubmit={form.handleSubmit(onSubmit)}>
14
+ * <FormInput form={form} id="email" name="Email" />
15
+ * </form>
16
+ * </Form>
17
+ * );
18
+ */
11
19
  const Form = FormProvider;
12
20
 
13
- type FormFieldContextValue<
14
- TFieldValues extends FieldValues = FieldValues,
15
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
16
- > = {
17
- name: TName;
18
- };
19
-
20
- const FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);
21
-
22
- const FormField = <
23
- TFieldValues extends FieldValues = FieldValues,
24
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
25
- >({
26
- ...props
27
- }: ControllerProps<TFieldValues, TName>) => {
28
- return (
29
- <FormFieldContext.Provider value={{ name: props.name }}>
30
- <Controller {...props} />
31
- </FormFieldContext.Provider>
32
- );
33
- };
34
-
35
- const useFormField = () => {
36
- const fieldContext = React.useContext(FormFieldContext);
37
- const itemContext = React.useContext(FormItemContext);
38
- const { getFieldState, formState } = useFormContext();
39
-
40
- const fieldState = getFieldState(fieldContext.name, formState);
41
-
42
- if (!fieldContext) {
43
- throw new Error("useFormField should be used within <FormField>");
44
- }
45
-
46
- const { id } = itemContext;
47
-
48
- return {
49
- id,
50
- name: fieldContext.name,
51
- formItemId: `${id}-form-item`,
52
- formDescriptionId: `${id}-form-item-description`,
53
- formMessageId: `${id}-form-item-message`,
54
- ...fieldState,
55
- };
56
- };
57
-
58
- type FormItemContextValue = {
59
- id: string;
60
- };
61
-
62
- const FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);
63
-
64
- const FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
65
- ({ className, ...props }, ref) => {
66
- const id = React.useId();
67
-
68
- return (
69
- <FormItemContext.Provider value={{ id }}>
70
- <div ref={ref} className={cn("space-y-2", className)} {...props} />
71
- </FormItemContext.Provider>
72
- );
73
- },
74
- );
75
- FormItem.displayName = "FormItem";
76
-
77
- const FormLabel = React.forwardRef<
78
- React.ElementRef<typeof LabelPrimitive.Root>,
79
- React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
80
- >(({ className, ...props }, ref) => {
81
- const { error, formItemId } = useFormField();
82
-
83
- return <Label ref={ref} className={cn(error && "text-destructive", className)} htmlFor={formItemId} {...props} />;
84
- });
85
- FormLabel.displayName = "FormLabel";
86
-
87
- const FormControl = React.forwardRef<React.ElementRef<typeof Slot>, React.ComponentPropsWithoutRef<typeof Slot>>(
88
- ({ ...props }, ref) => {
89
- const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
90
-
91
- return (
92
- <Slot
93
- ref={ref}
94
- id={formItemId}
95
- aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}
96
- aria-invalid={!!error}
97
- {...props}
98
- />
99
- );
100
- },
101
- );
102
- FormControl.displayName = "FormControl";
103
-
104
- const FormDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
105
- ({ className, ...props }, ref) => {
106
- const { formDescriptionId } = useFormField();
107
-
108
- return (
109
- <p ref={ref} id={formDescriptionId} className={cn("text-muted-foreground text-[0.8rem]", className)} {...props} />
110
- );
111
- },
112
- );
113
- FormDescription.displayName = "FormDescription";
114
-
115
- const FormMessage = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
116
- ({ className, children, ...props }, ref) => {
117
- const { error, formMessageId } = useFormField();
118
- const body = error ? String(error?.message) : children;
119
-
120
- if (!body) {
121
- return null;
122
- }
123
-
124
- return (
125
- <p
126
- ref={ref}
127
- id={formMessageId}
128
- className={cn("text-destructive text-[0.8rem] font-medium", className)}
129
- {...props}
130
- >
131
- {body}
132
- </p>
133
- );
134
- },
135
- );
136
- FormMessage.displayName = "FormMessage";
137
-
138
- export { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField };
21
+ export { Form };
@@ -3,10 +3,10 @@
3
3
  import * as React from "react"
4
4
  import { cva, type VariantProps } from "class-variance-authority"
5
5
 
6
- import { cn } from "@/lib/utils"
7
- import { Button } from "@/components/ui/button"
8
- import { Input } from "@/components/ui/input"
9
- import { Textarea } from "@/components/ui/textarea"
6
+ import { cn } from "../../utils/cn"
7
+ import { Button } from "./button"
8
+ import { Input } from "./input"
9
+ import { Textarea } from "./textarea"
10
10
 
11
11
  function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
12
12
  return (
@@ -8,12 +8,12 @@ import { cn } from "@/lib/utils"
8
8
  function ResizablePanelGroup({
9
9
  className,
10
10
  ...props
11
- }: React.ComponentProps<typeof ResizablePrimitive.Group>) {
11
+ }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) {
12
12
  return (
13
- <ResizablePrimitive.Group
13
+ <ResizablePrimitive.PanelGroup
14
14
  data-slot="resizable-panel-group"
15
15
  className={cn(
16
- "flex h-full w-full aria-[orientation=vertical]:flex-col",
16
+ "flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
17
17
  className
18
18
  )}
19
19
  {...props}
@@ -31,22 +31,22 @@ function ResizableHandle({
31
31
  withHandle,
32
32
  className,
33
33
  ...props
34
- }: React.ComponentProps<typeof ResizablePrimitive.Separator> & {
34
+ }: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
35
35
  withHandle?: boolean
36
36
  }) {
37
37
  return (
38
- <ResizablePrimitive.Separator
38
+ <ResizablePrimitive.PanelResizeHandle
39
39
  data-slot="resizable-handle"
40
40
  className={cn(
41
- "bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden aria-[orientation=vertical]:h-px aria-[orientation=vertical]:w-full aria-[orientation=vertical]:after:left-0 aria-[orientation=vertical]:after:h-1 aria-[orientation=vertical]:after:w-full aria-[orientation=vertical]:after:translate-x-0 aria-[orientation=vertical]:after:-translate-y-1/2 [&[aria-orientation=vertical]>div]:rotate-90",
41
+ "bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90",
42
42
  className
43
43
  )}
44
44
  {...props}
45
45
  >
46
46
  {withHandle && (
47
- <div className="bg-border h-6 w-1 rounded-lg z-10 flex shrink-0" />
47
+ <div className="bg-border z-10 flex h-6 w-1 shrink-0 rounded-lg" />
48
48
  )}
49
- </ResizablePrimitive.Separator>
49
+ </ResizablePrimitive.PanelResizeHandle>
50
50
  )
51
51
  }
52
52