@granto-umbrella/umbrella-components 2.0.8 → 2.2.0

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.
@@ -0,0 +1,158 @@
1
+ import * as React from "react";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import {
4
+ Controller,
5
+ ControllerProps,
6
+ FieldPath,
7
+ FieldValues,
8
+ FormProvider,
9
+ useFormContext,
10
+ } from "react-hook-form";
11
+ import {
12
+ StyledFormItem,
13
+ StyledFormLabel,
14
+ StyledFormDescription,
15
+ StyledFormMessage,
16
+ } from "./Form.styles";
17
+
18
+ /* Reexporta o FormProvider como Form para facilitar o uso */
19
+ const Form = FormProvider;
20
+
21
+ type FormFieldContextValue<
22
+ TFieldValues extends FieldValues = FieldValues,
23
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
24
+ > = {
25
+ name: TName;
26
+ };
27
+
28
+ const FormFieldContext = React.createContext<FormFieldContextValue>(
29
+ {} as FormFieldContextValue
30
+ );
31
+
32
+ const FormField = <
33
+ TFieldValues extends FieldValues = FieldValues,
34
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
35
+ >({
36
+ ...props
37
+ }: ControllerProps<TFieldValues, TName>) => {
38
+ return (
39
+ <FormFieldContext.Provider value={{ name: props.name }}>
40
+ <Controller {...props} />
41
+ </FormFieldContext.Provider>
42
+ );
43
+ };
44
+
45
+ type FormItemContextValue = { id: string };
46
+
47
+ const FormItemContext = React.createContext<FormItemContextValue>(
48
+ {} as FormItemContextValue
49
+ );
50
+
51
+ const FormItem = React.forwardRef<
52
+ HTMLDivElement,
53
+ React.HTMLAttributes<HTMLDivElement>
54
+ >(({ ...props }, ref) => {
55
+ const id = React.useId();
56
+ return (
57
+ <FormItemContext.Provider value={{ id }}>
58
+ <StyledFormItem ref={ref} {...props} />
59
+ </FormItemContext.Provider>
60
+ );
61
+ });
62
+ FormItem.displayName = "FormItem";
63
+
64
+ const useFormField = () => {
65
+ const fieldContext = React.useContext(FormFieldContext);
66
+ const itemContext = React.useContext(FormItemContext);
67
+ const { getFieldState, formState } = useFormContext();
68
+
69
+ const fieldState = getFieldState(fieldContext.name, formState);
70
+
71
+ if (!fieldContext) {
72
+ throw new Error("useFormField should be used within <FormField>");
73
+ }
74
+
75
+ const { id } = itemContext;
76
+ return {
77
+ id,
78
+ name: fieldContext.name,
79
+ formItemId: `${id}-form-item`,
80
+ formDescriptionId: `${id}-form-item-description`,
81
+ formMessageId: `${id}-form-item-message`,
82
+ ...fieldState,
83
+ };
84
+ };
85
+
86
+ const FormLabel = React.forwardRef<
87
+ HTMLLabelElement,
88
+ React.ComponentPropsWithoutRef<"label">
89
+ >(({ children, ...props }, ref) => {
90
+ const { error, formItemId } = useFormField();
91
+ return (
92
+ <StyledFormLabel ref={ref} htmlFor={formItemId} error={!!error} {...props}>
93
+ {children}
94
+ </StyledFormLabel>
95
+ );
96
+ });
97
+ FormLabel.displayName = "FormLabel";
98
+
99
+ const FormControl = React.forwardRef<
100
+ React.ElementRef<typeof Slot>,
101
+ React.ComponentPropsWithoutRef<typeof Slot>
102
+ >(({ ...props }, ref) => {
103
+ const { error, formItemId, formDescriptionId, formMessageId } =
104
+ useFormField();
105
+ return (
106
+ <Slot
107
+ ref={ref}
108
+ id={formItemId}
109
+ aria-describedby={
110
+ !error
111
+ ? `${formDescriptionId}`
112
+ : `${formDescriptionId} ${formMessageId}`
113
+ }
114
+ aria-invalid={!!error}
115
+ {...props}
116
+ />
117
+ );
118
+ });
119
+ FormControl.displayName = "FormControl";
120
+
121
+ const FormDescription = React.forwardRef<
122
+ HTMLParagraphElement,
123
+ React.HTMLAttributes<HTMLParagraphElement>
124
+ >(({ children, ...props }, ref) => {
125
+ const { formDescriptionId } = useFormField();
126
+ return (
127
+ <StyledFormDescription ref={ref} id={formDescriptionId} {...props}>
128
+ {children}
129
+ </StyledFormDescription>
130
+ );
131
+ });
132
+ FormDescription.displayName = "FormDescription";
133
+
134
+ const FormMessage = React.forwardRef<
135
+ HTMLParagraphElement,
136
+ React.HTMLAttributes<HTMLParagraphElement>
137
+ >(({ children, ...props }, ref) => {
138
+ const { error, formMessageId } = useFormField();
139
+ const body = error ? String(error?.message) : children;
140
+ if (!body) return null;
141
+ return (
142
+ <StyledFormMessage ref={ref} id={formMessageId} {...props}>
143
+ {body}
144
+ </StyledFormMessage>
145
+ );
146
+ });
147
+ FormMessage.displayName = "FormMessage";
148
+
149
+ export {
150
+ useFormField,
151
+ Form,
152
+ FormItem,
153
+ FormLabel,
154
+ FormControl,
155
+ FormDescription,
156
+ FormMessage,
157
+ FormField,
158
+ };
package/src/index.ts CHANGED
@@ -12,7 +12,7 @@ import { Checkbox } from "./components/atoms/Checkbox/Checkbox";
12
12
  import Switch from "./components/atoms/Switch/Switch";
13
13
  import Text from "./components/atoms/Text";
14
14
  import Textarea from "./components/atoms/Textarea/Textarea";
15
- import ButtonGroup from "./components/molecules/ButtonGroup";
15
+ import ButtonGroup from "./components/molecules/ButtonGroup/ButtonGroup";
16
16
 
17
17
  // Export all components
18
18
  export {