@carlonicora/nextjs-jsonapi 1.24.2 → 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.
- package/dist/{BlockNoteEditor-7OSPCSFW.js → BlockNoteEditor-OFSTXGZX.js} +6 -6
- package/dist/{BlockNoteEditor-7OSPCSFW.js.map → BlockNoteEditor-OFSTXGZX.js.map} +1 -1
- package/dist/{BlockNoteEditor-63GKCJK3.mjs → BlockNoteEditor-TJNLCNIP.mjs} +2 -2
- package/dist/billing/index.js +300 -303
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +5 -8
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-HIKTQMCR.js → chunk-EJALOG7L.js} +3989 -3911
- package/dist/chunk-EJALOG7L.js.map +1 -0
- package/dist/{chunk-UTPWUC6O.mjs → chunk-H5JZ5E7M.mjs} +4325 -4247
- package/dist/chunk-H5JZ5E7M.mjs.map +1 -0
- package/dist/client/index.js +2 -2
- package/dist/client/index.mjs +1 -1
- package/dist/components/index.d.mts +67 -32
- package/dist/components/index.d.ts +67 -32
- package/dist/components/index.js +20 -2
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +35 -17
- package/dist/contexts/index.js +2 -2
- package/dist/contexts/index.mjs +1 -1
- package/dist/scripts/generate-web-module/templates/components/editor.template.js +11 -13
- package/dist/scripts/generate-web-module/templates/components/editor.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/multi-selector.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/multi-selector.template.js +13 -26
- package/dist/scripts/generate-web-module/templates/components/multi-selector.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/selector.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/selector.template.js +59 -76
- package/dist/scripts/generate-web-module/templates/components/selector.template.js.map +1 -1
- package/dist/scripts/generate-web-module/transformers/field-mapper.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/transformers/field-mapper.js +10 -12
- package/dist/scripts/generate-web-module/transformers/field-mapper.js.map +1 -1
- package/package.json +1 -1
- package/scripts/generate-web-module/templates/components/editor.template.ts +11 -13
- package/scripts/generate-web-module/templates/components/multi-selector.template.ts +13 -26
- package/scripts/generate-web-module/templates/components/selector.template.ts +59 -76
- package/scripts/generate-web-module/transformers/field-mapper.ts +10 -12
- package/src/components/forms/FormCheckbox.tsx +18 -24
- package/src/components/forms/FormDate.tsx +103 -116
- package/src/components/forms/FormDateTime.tsx +122 -130
- package/src/components/forms/FormFieldWrapper.tsx +54 -0
- package/src/components/forms/FormInput.tsx +58 -46
- package/src/components/forms/FormPassword.tsx +17 -24
- package/src/components/forms/FormPlaceAutocomplete.tsx +50 -75
- package/src/components/forms/FormSelect.tsx +29 -35
- package/src/components/forms/FormSlider.tsx +23 -27
- package/src/components/forms/FormSwitch.tsx +12 -14
- package/src/components/forms/FormTextarea.tsx +12 -19
- package/src/components/forms/index.ts +1 -1
- package/src/features/billing/stripe-price/components/forms/PriceEditor.tsx +9 -13
- package/src/features/company/components/forms/CompanyConfigurationSecurityForm.tsx +19 -33
- package/src/features/feature/components/forms/FormFeatures.tsx +3 -4
- package/src/features/role/components/forms/FormRoles.tsx +40 -51
- package/src/features/user/components/forms/UserMultiSelect.tsx +12 -29
- package/src/features/user/components/forms/UserSelector.tsx +79 -91
- package/src/shadcnui/index.ts +2 -0
- package/src/shadcnui/ui/field.tsx +3 -3
- package/src/shadcnui/ui/form.tsx +17 -134
- package/src/shadcnui/ui/input-group.tsx +4 -4
- package/dist/chunk-HIKTQMCR.js.map +0 -1
- package/dist/chunk-UTPWUC6O.mjs.map +0 -1
- package/src/components/forms/FormContainerGeneric.tsx +0 -39
- /package/dist/{BlockNoteEditor-63GKCJK3.mjs.map → BlockNoteEditor-TJNLCNIP.mjs.map} +0 -0
|
@@ -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
|
-
<
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
{
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
<
|
|
96
|
-
|
|
91
|
+
<FormFieldWrapper
|
|
92
|
+
form={form}
|
|
97
93
|
name={id}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
<
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
}
|
package/src/shadcnui/index.ts
CHANGED
|
@@ -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 "
|
|
7
|
-
import { Label } from "
|
|
8
|
-
import { Separator } from "
|
|
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 (
|
package/src/shadcnui/ui/form.tsx
CHANGED
|
@@ -1,138 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
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 "
|
|
7
|
-
import { Button } from "
|
|
8
|
-
import { Input } from "
|
|
9
|
-
import { Textarea } from "
|
|
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 (
|