@twintag/twintag-form 0.4.2 → 0.5.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.
Files changed (75) hide show
  1. package/.turbo/turbo-build.log +10 -54
  2. package/CHANGELOG.md +17 -0
  3. package/README.md +9 -9
  4. package/dist/components/Category/__styles.d.ts +19 -0
  5. package/dist/{lib/components → components}/Category/index.d.ts +2 -3
  6. package/dist/components/Form/index.d.ts +12 -0
  7. package/dist/{lib/types/index.d.ts → components/Input/__props.d.ts} +0 -6
  8. package/dist/components/Input/__styles.d.ts +245 -0
  9. package/dist/{lib/components → components}/Input/checkbox.d.ts +2 -3
  10. package/dist/{lib/components → components}/Input/file.d.ts +2 -3
  11. package/dist/{lib/components → components}/Input/index.d.ts +0 -1
  12. package/dist/{lib/components → components}/Input/simple.d.ts +2 -3
  13. package/dist/{lib/components → components}/Input/submit.d.ts +2 -3
  14. package/dist/{lib/components → components}/Input/textarea.d.ts +2 -3
  15. package/dist/{lib/components → components}/Input/toggle.d.ts +2 -3
  16. package/dist/{lib/components → components}/Label/index.d.ts +0 -1
  17. package/dist/components/index.d.ts +4 -0
  18. package/dist/index.d.ts +14 -0
  19. package/dist/react.d.ts +1 -0
  20. package/dist/styles.d.ts +262 -0
  21. package/dist/twintag-form.react.js +8658 -0
  22. package/dist/twintag-form.webcomponent.js +4503 -0
  23. package/dist/webcomponent.d.ts +1 -0
  24. package/lib/__stories__/Form.stories.tsx +102 -10
  25. package/lib/components/Category/__styles.ts +12 -0
  26. package/lib/components/Category/index.tsx +5 -8
  27. package/lib/components/Form/index.tsx +33 -34
  28. package/lib/{types/index.ts → components/Input/__props.ts} +0 -6
  29. package/lib/components/Input/__styles.ts +132 -0
  30. package/lib/components/Input/checkbox.tsx +8 -11
  31. package/lib/components/Input/file.tsx +9 -12
  32. package/lib/components/Input/simple.tsx +8 -10
  33. package/lib/components/Input/submit.tsx +3 -9
  34. package/lib/components/Input/textarea.tsx +8 -10
  35. package/lib/components/Input/toggle.tsx +10 -11
  36. package/lib/components/Label/index.tsx +2 -1
  37. package/lib/components/index.tsx +4 -6
  38. package/lib/index.tsx +35 -157
  39. package/lib/styles.ts +2 -1
  40. package/lib/webcomponent.ts +1 -1
  41. package/package.json +11 -14
  42. package/tsconfig.json +3 -2
  43. package/vite.config.ts +47 -0
  44. package/dist/index.es.js +0 -27362
  45. package/dist/index.umd.js +0 -196
  46. package/dist/lib/__stories__/Form.stories.d.ts +0 -7
  47. package/dist/lib/__stories__/Form.stories.d.ts.map +0 -1
  48. package/dist/lib/components/Category/index.d.ts.map +0 -1
  49. package/dist/lib/components/Form/index.d.ts +0 -10
  50. package/dist/lib/components/Form/index.d.ts.map +0 -1
  51. package/dist/lib/components/Form/register.d.ts +0 -12
  52. package/dist/lib/components/Form/register.d.ts.map +0 -1
  53. package/dist/lib/components/Input/checkbox.d.ts.map +0 -1
  54. package/dist/lib/components/Input/file.d.ts.map +0 -1
  55. package/dist/lib/components/Input/index.d.ts.map +0 -1
  56. package/dist/lib/components/Input/simple.d.ts.map +0 -1
  57. package/dist/lib/components/Input/submit.d.ts.map +0 -1
  58. package/dist/lib/components/Input/textarea.d.ts.map +0 -1
  59. package/dist/lib/components/Input/toggle.d.ts.map +0 -1
  60. package/dist/lib/components/Label/index.d.ts.map +0 -1
  61. package/dist/lib/components/index.d.ts +0 -6
  62. package/dist/lib/components/index.d.ts.map +0 -1
  63. package/dist/lib/index.d.ts +0 -20
  64. package/dist/lib/index.d.ts.map +0 -1
  65. package/dist/lib/styles.d.ts +0 -131
  66. package/dist/lib/styles.d.ts.map +0 -1
  67. package/dist/lib/types/index.d.ts.map +0 -1
  68. package/dist/lib/webcomponent.d.ts +0 -2
  69. package/dist/lib/webcomponent.d.ts.map +0 -1
  70. package/dist/twind.config.d.ts +0 -5
  71. package/dist/twind.config.d.ts.map +0 -1
  72. package/dist/webcomponent.es.js +0 -31726
  73. package/dist/webcomponent.umd.js +0 -196
  74. package/lib/components/Form/register.tsx +0 -69
  75. package/scripts/build.js +0 -60
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import TwintagForm from '../index';
1
+ import { TwintagForm } from '@twintag-form/index';
2
2
 
3
3
  // Replace your-framework with the name of your framework
4
4
  import type { Meta, StoryObj } from '@storybook/react';
@@ -28,18 +28,110 @@ export const Example: Story = {
28
28
  args: {
29
29
  config: [
30
30
  {
31
+ id: 'category-123',
31
32
  type: 'category',
32
- label: 'Category test',
33
- items: [
34
- { type: 'input', label: 'Test', bind: 'test' },
35
- { type: 'input:toggle', label: 'Email', bind: 'email' },
36
- { type: 'input:file', label: 'File test', bind: 'fileTest' },
33
+ props: {
34
+ label: 'Category 1st',
35
+ },
36
+ content: [],
37
+ children: [
38
+ {
39
+ id: 'input-123',
40
+ type: 'input',
41
+ props: {
42
+ subtype: 'toggle',
43
+ label: 'Require',
44
+ bind: 'require',
45
+ },
46
+ content: [],
47
+ children: [],
48
+ },
37
49
  ],
38
50
  },
39
- { type: 'input:file', label: 'Image', bind: 'image' },
40
- { type: 'input:checkbox', label: 'Checkbox', bind: 'checkbox' },
41
- { type: 'input:checkbox', label: 'Checkbox Test', bind: 'checkTest' },
42
- { type: 'input:submit', label: 'Submit' },
51
+ {
52
+ id: 'category-456',
53
+ type: 'category',
54
+ props: {
55
+ label: 'Category 2nd',
56
+ },
57
+ content: [],
58
+ children: [
59
+ {
60
+ id: 'input-123',
61
+ type: 'input',
62
+ props: {
63
+ subtype: 'simple',
64
+ label: 'Name',
65
+ bind: 'name',
66
+ },
67
+ content: [],
68
+ children: [],
69
+ },
70
+ {
71
+ id: 'input-456',
72
+ type: 'input',
73
+ props: {
74
+ subtype: 'simple',
75
+ label: 'Email',
76
+ bind: 'email',
77
+ },
78
+ content: [],
79
+ children: [],
80
+ },
81
+ ],
82
+ },
83
+ {
84
+ id: 'category-789',
85
+ type: 'category',
86
+ props: {
87
+ label: 'Category 3rd',
88
+ },
89
+ content: [],
90
+ children: [
91
+ {
92
+ id: 'input-789',
93
+ type: 'input',
94
+ props: {
95
+ subtype: 'file',
96
+ label: 'File',
97
+ bind: 'file',
98
+ },
99
+ content: [],
100
+ children: [],
101
+ },
102
+ ],
103
+ },
104
+ {
105
+ id: 'category-321',
106
+ type: 'category',
107
+ props: {
108
+ label: 'Category 4th',
109
+ },
110
+ content: [],
111
+ children: [
112
+ {
113
+ id: 'input-123',
114
+ type: 'input',
115
+ props: {
116
+ subtype: 'checkbox',
117
+ label: 'Checkbox',
118
+ bind: 'checkbox',
119
+ },
120
+ content: [],
121
+ children: [],
122
+ },
123
+ ],
124
+ },
125
+ {
126
+ id: 'input-654',
127
+ type: 'input',
128
+ props: {
129
+ subtype: 'submit',
130
+ label: 'Submit',
131
+ },
132
+ content: [],
133
+ children: [],
134
+ },
43
135
  ],
44
136
  options: {
45
137
  variant: 'beta',
@@ -0,0 +1,12 @@
1
+ import { tv } from 'tailwind-variants';
2
+
3
+ export const categoryStyle = tv({
4
+ slots: {
5
+ container: 'w-full space-y-4',
6
+ span: 'text-category-label',
7
+ items: 'space-y-2',
8
+ },
9
+ variants: {
10
+ variant: {},
11
+ },
12
+ });
@@ -2,20 +2,17 @@ import type { FC } from 'react';
2
2
  import type { VariantProps } from 'tailwind-variants';
3
3
  import type { WithChildren } from 'twintag-types/dom';
4
4
 
5
- import { useMemo } from 'react';
5
+ import type { CommonProps } from '../Input/__props';
6
6
 
7
- import type { CommonProps } from '@twintag-form/types';
8
-
9
- import { categoryStyle } from '@twintag-form/styles';
7
+ import { categoryStyle } from './__styles';
10
8
 
11
9
  type Props = CommonProps<VariantProps<typeof categoryStyle>['variant']> &
12
10
  WithChildren;
13
11
 
14
12
  const Category: FC<Props> = ({ label, options, children }) => {
15
- const { container, span, items } = useMemo(() => {
16
- if (options?.variant) return categoryStyle({ variant: options.variant });
17
- return categoryStyle();
18
- }, []);
13
+ const { container, span, items } = categoryStyle({
14
+ variant: options?.variant,
15
+ });
19
16
 
20
17
  return (
21
18
  <section className={container()}>
@@ -1,11 +1,13 @@
1
- import type { FC } from 'react';
1
+ import type { Ref } from 'react';
2
2
  import type { FieldValues } from 'react-hook-form';
3
3
  import type { WithChildren } from 'twintag-types/dom';
4
4
 
5
- import { useEffect, useRef } from 'react';
6
- import { useForm } from 'react-hook-form';
5
+ import { useEffect, useRef, useImperativeHandle, forwardRef } from 'react';
6
+ import { useForm, FormProvider } from 'react-hook-form';
7
7
 
8
- import { RegisterInputs } from './register';
8
+ type FormRef = Ref<{
9
+ validate: () => void;
10
+ } | null>;
9
11
 
10
12
  type Props = {
11
13
  options?: {
@@ -13,20 +15,20 @@ type Props = {
13
15
  };
14
16
  } & WithChildren;
15
17
 
16
- const Form: FC<Props> = ({ children, options }) => {
18
+ const Form = forwardRef(({ options, children }: Props, ref: FormRef) => {
19
+ const { formState, reset, ...methods } = useForm();
20
+
17
21
  const formRef = useRef<HTMLFormElement>(null);
18
22
 
19
- const {
20
- reset,
21
- register,
22
- handleSubmit,
23
- formState: { isSubmitSuccessful },
24
- control,
25
- } = useForm();
23
+ useImperativeHandle(ref, () => ({
24
+ validate: () => onValidate(),
25
+ }));
26
26
 
27
27
  useEffect(() => {
28
- if (isSubmitSuccessful && options?.resetOnSubmit) reset();
29
- }, [isSubmitSuccessful]);
28
+ if (formState.isSubmitSuccessful && options?.resetOnSubmit) {
29
+ reset();
30
+ }
31
+ }, [formState, reset]);
30
32
 
31
33
  const onValid = (data: FieldValues) => {
32
34
  const customSubmit = new CustomEvent('twintag-form-valid', {
@@ -51,37 +53,34 @@ const Form: FC<Props> = ({ children, options }) => {
51
53
  };
52
54
 
53
55
  const onValidate = () => {
54
- handleSubmit(onValid, onInvalid)();
56
+ methods.handleSubmit(onValid, onInvalid)();
55
57
  };
56
58
 
57
59
  useEffect(() => {
58
- if (formRef.current) {
59
- formRef.current.addEventListener('twintag-form-validate', onValidate);
60
+ const form = formRef.current;
61
+
62
+ if (form) {
63
+ form.addEventListener('twintag-form-validate', onValidate);
60
64
  }
61
65
 
62
66
  return () => {
63
- if (formRef.current) {
64
- formRef.current.removeEventListener(
65
- 'twintag-form-validate',
66
- onValidate
67
- );
67
+ if (form) {
68
+ form.removeEventListener('twintag-form-validate', onValidate);
68
69
  }
69
70
  };
70
71
  }, []);
71
72
 
72
73
  return (
73
- <form
74
- ref={formRef}
75
- className='font-ff-text relative'
76
- onSubmit={handleSubmit(onValid, onInvalid)}
77
- >
78
- <div className='grid w-auto'>
79
- <RegisterInputs useForm={{ register, control }}>
80
- {children}
81
- </RegisterInputs>
82
- </div>
83
- </form>
74
+ <FormProvider {...{ formState, reset, ...methods }}>
75
+ <form
76
+ ref={formRef}
77
+ className='font-ff-text relative'
78
+ onSubmit={methods.handleSubmit(onValid, onInvalid)}
79
+ >
80
+ <div className='w-full space-y-4'>{children}</div>
81
+ </form>
82
+ </FormProvider>
84
83
  );
85
- };
84
+ });
86
85
 
87
86
  export default Form;
@@ -1,12 +1,6 @@
1
- import type { UseFormRegister, Control } from 'react-hook-form';
2
-
3
1
  export type CommonProps<TVariant> = {
4
2
  label: string;
5
3
  bind: string;
6
- useForm?: {
7
- register: UseFormRegister<any>;
8
- control: Control;
9
- };
10
4
  checked?: boolean;
11
5
  options?: {
12
6
  variant?: TVariant;
@@ -0,0 +1,132 @@
1
+ import { tv } from 'tailwind-variants';
2
+
3
+ export const labelStyle = tv({
4
+ base: 'text-label',
5
+ });
6
+
7
+ export const containerStyle = tv({
8
+ base: '',
9
+ });
10
+
11
+ export const checkboxStyle = tv({
12
+ slots: {
13
+ container: containerStyle({
14
+ className: 'flex gap-4 items-center w-full',
15
+ }),
16
+ checkbox:
17
+ 'flex appearance-none items-center justify-center bg-white outline-none ring-0 border-2 border-primary focus:ring-0 focus:border-accent',
18
+ },
19
+ variants: {
20
+ variant: {
21
+ alpha: {
22
+ checkbox: 'h-5 w-5 rounded',
23
+ },
24
+ beta: {
25
+ checkbox: 'h-5 w-5',
26
+ },
27
+ },
28
+ },
29
+ defaultVariants: {
30
+ variant: 'alpha',
31
+ },
32
+ });
33
+
34
+ export const fileStyle = tv({
35
+ slots: {
36
+ container: containerStyle({
37
+ className: 'w-full block',
38
+ }),
39
+ span: '',
40
+ input:
41
+ 'w-full cursor-pointer ring-0 focus:ring-0 border-2 border-transparent',
42
+ },
43
+ variants: {
44
+ variant: {
45
+ alpha: {
46
+ container: 'grid gap-1.5',
47
+ input:
48
+ 'flex items-center justify-between gap-4 rounded-md px-3 py-2 border-slate-700/10 peer-focus:border-accent',
49
+ },
50
+ beta: {
51
+ container: 'grid gap-0',
52
+ input:
53
+ 'flex items-center justify-between gap-4 py-2 border-b-slate-700/10 peer-focus:border-b-accent',
54
+ },
55
+ },
56
+ },
57
+ defaultVariants: {
58
+ variant: 'alpha',
59
+ },
60
+ });
61
+
62
+ export const simpleStyle = tv({
63
+ slots: {
64
+ container: containerStyle({
65
+ className: 'w-full',
66
+ }),
67
+ span: '',
68
+ input:
69
+ 'w-full ring-0 placeholder:text-placeholder focus:ring-0 border-2 border-transparent text-input',
70
+ },
71
+ variants: {
72
+ variant: {
73
+ alpha: {
74
+ container: 'grid gap-1.5',
75
+ input: 'rounded-md border-slate-700/10 focus:border-accent',
76
+ },
77
+ beta: {
78
+ container: 'grid gap-0',
79
+ input:
80
+ 'px-0 focus:border-transparent focus:border-b-accent border-b-slate-700/10',
81
+ },
82
+ },
83
+ },
84
+ defaultVariants: {
85
+ variant: 'alpha',
86
+ },
87
+ });
88
+
89
+ export const toggleStyle = tv({
90
+ slots: {
91
+ container: containerStyle({
92
+ className: 'w-full cursor-pointer',
93
+ }),
94
+ span: '',
95
+ input: 'relative outline-none ring-2 ring-transparent',
96
+ thumb: 'block transition-transform duration-100 will-change-transform',
97
+ },
98
+ variants: {
99
+ variant: {
100
+ alpha: {
101
+ container: 'flex justify-between',
102
+ input:
103
+ 'h-6 w-9 rounded-full bg-primary border border-black ring-2 focus:border-transparent focus:ring-accent data-[state=checked]:bg-white',
104
+ thumb:
105
+ 'h-4 w-4 translate-x-0.5 rounded-full bg-white data-[state=checked]:translate-x-4 data-[state=checked]:bg-primary',
106
+ },
107
+ beta: {
108
+ container: 'flex justify-between',
109
+ input:
110
+ 'h-6 w-9 rounded-full bg-primary border border-black ring-2 focus:border-transparent focus:ring-accent data-[state=checked]:bg-white',
111
+ thumb:
112
+ 'h-4 w-4 translate-x-0.5 rounded-full bg-white data-[state=checked]:translate-x-4 data-[state=checked]:bg-primary',
113
+ },
114
+ },
115
+ },
116
+ defaultVariants: {
117
+ variant: 'alpha',
118
+ },
119
+ });
120
+
121
+ export const submitStyle = tv({
122
+ base: 'w-max max-w-full mt-2',
123
+ variants: {
124
+ variant: {
125
+ alpha: 'bg-primary text-white px-4 py-2 rounded-md',
126
+ beta: 'bg-primary text-white px-4 py-2',
127
+ },
128
+ },
129
+ defaultVariants: {
130
+ variant: 'alpha',
131
+ },
132
+ });
@@ -1,35 +1,32 @@
1
1
  import type { FC } from 'react';
2
2
  import type { VariantProps } from 'tailwind-variants';
3
3
 
4
- import { useMemo } from 'react';
5
- import { useController } from 'react-hook-form';
4
+ import { useController, useFormContext } from 'react-hook-form';
6
5
  import { CheckIcon } from '@heroicons/react/24/outline';
7
6
  import * as RdxCheckbox from '@radix-ui/react-checkbox';
8
7
 
9
- import type { CommonProps } from '@twintag-form/types';
10
-
11
8
  import { Label } from '@twintag-form/components';
12
- import { checkboxStyle } from '@twintag-form/styles';
9
+ import { type CommonProps } from './__props';
10
+ import { checkboxStyle } from './__styles';
13
11
 
14
12
  type Props = CommonProps<VariantProps<typeof checkboxStyle>['variant']>;
15
13
 
16
- const Checkbox: FC<Props> = ({ useForm, label, bind, options }) => {
17
- const { container, checkbox } = useMemo(() => {
18
- if (options?.variant) return checkboxStyle({ variant: options.variant });
19
- return checkboxStyle();
20
- }, []);
14
+ const Checkbox: FC<Props> = ({ label, bind, options }) => {
15
+ const { control } = useFormContext();
21
16
 
22
17
  const {
23
18
  field: { ref, value, onChange },
24
19
  } = useController({
20
+ control,
25
21
  name: bind,
26
- control: useForm ? useForm.control : undefined,
27
22
  defaultValue: false,
28
23
  rules: {
29
24
  required: options?.optionalField ? false : `${label} is required`,
30
25
  },
31
26
  });
32
27
 
28
+ const { container, checkbox } = checkboxStyle({ variant: options?.variant });
29
+
33
30
  return (
34
31
  <label className={container()}>
35
32
  <RdxCheckbox.Root
@@ -1,34 +1,31 @@
1
1
  import type { FC } from 'react';
2
2
  import type { VariantProps } from 'tailwind-variants';
3
3
 
4
- import { useMemo } from 'react';
5
- import { useController } from 'react-hook-form';
4
+ import { useController, useFormContext } from 'react-hook-form';
6
5
  import { CloudArrowUpIcon } from '@heroicons/react/24/outline';
7
6
 
8
- import type { CommonProps } from '@twintag-form/types';
9
-
10
7
  import { Label } from '@twintag-form/components';
11
- import { fileStyle } from '@twintag-form/styles';
8
+ import { type CommonProps } from './__props';
9
+ import { fileStyle } from './__styles';
12
10
 
13
11
  type Props = CommonProps<VariantProps<typeof fileStyle>['variant']>;
14
12
 
15
- const File: FC<Props> = ({ useForm, label, bind, options }) => {
16
- const { container, span, input } = useMemo(() => {
17
- if (options?.variant) return fileStyle({ variant: options?.variant });
18
- return fileStyle();
19
- }, []);
13
+ const File: FC<Props> = ({ label, bind, options }) => {
14
+ const { control } = useFormContext();
20
15
 
21
16
  const {
22
17
  field: { ref, value, onChange },
23
18
  } = useController({
19
+ control,
24
20
  name: bind,
25
- control: useForm ? useForm.control : undefined,
26
21
  defaultValue: null,
27
22
  rules: {
28
23
  required: options?.optionalField ? false : `${label} is required`,
29
24
  },
30
25
  });
31
26
 
27
+ const { container, span, input } = fileStyle({ variant: options?.variant });
28
+
32
29
  return (
33
30
  <label className={container()}>
34
31
  {label ? (
@@ -56,7 +53,7 @@ const File: FC<Props> = ({ useForm, label, bind, options }) => {
56
53
  className={`${input()} ${
57
54
  value && value.length > 0
58
55
  ? 'border-primary text-input'
59
- : 'border-slate-700/10 text-placeholder'
56
+ : 'text-placeholder border-slate-700/10'
60
57
  }`}
61
58
  >
62
59
  <span className='grid'>
@@ -1,20 +1,18 @@
1
1
  import type { FC } from 'react';
2
2
  import type { VariantProps } from 'tailwind-variants';
3
3
 
4
- import { useMemo } from 'react';
5
-
6
- import type { CommonProps } from '@twintag-form/types';
4
+ import { useFormContext } from 'react-hook-form';
7
5
 
8
6
  import { Label } from '@twintag-form/components';
9
- import { simpleStyle } from '@twintag-form/styles';
7
+ import { type CommonProps } from './__props';
8
+ import { simpleStyle } from './__styles';
10
9
 
11
10
  type Props = CommonProps<VariantProps<typeof simpleStyle>['variant']>;
12
11
 
13
- const Simple: FC<Props> = ({ useForm, label, bind, options }) => {
14
- const { container, span, input } = useMemo(() => {
15
- if (options?.variant) return simpleStyle({ variant: options.variant });
16
- return simpleStyle();
17
- }, []);
12
+ const Simple: FC<Props> = ({ label, bind, options }) => {
13
+ const { container, span, input } = simpleStyle({ variant: options?.variant });
14
+
15
+ const { register } = useFormContext();
18
16
 
19
17
  return (
20
18
  <label className={container()}>
@@ -30,7 +28,7 @@ const Simple: FC<Props> = ({ useForm, label, bind, options }) => {
30
28
  type='text'
31
29
  placeholder={options?.placeholder || 'Write here...'}
32
30
  className={input()}
33
- {...useForm!.register(bind, {
31
+ {...register(bind, {
34
32
  required: options?.optionalField ? false : `${label} is required`,
35
33
  })}
36
34
  />
@@ -1,19 +1,13 @@
1
1
  import type { FC } from 'react';
2
2
  import type { VariantProps } from 'tailwind-variants';
3
3
 
4
- import { useMemo } from 'react';
5
-
6
- import type { CommonProps } from '@twintag-form/types';
7
-
8
- import { submitStyle } from '@twintag-form/styles';
4
+ import { type CommonProps } from './__props';
5
+ import { submitStyle } from './__styles';
9
6
 
10
7
  type Props = CommonProps<VariantProps<typeof submitStyle>['variant']>;
11
8
 
12
9
  const Submit: FC<Props> = ({ label, options }) => {
13
- const style = useMemo(() => {
14
- if (options?.variant) return submitStyle({ variant: options.variant });
15
- return submitStyle();
16
- }, []);
10
+ const style = submitStyle({ variant: options?.variant });
17
11
 
18
12
  return (
19
13
  <div className='flex w-full justify-center'>
@@ -1,20 +1,18 @@
1
1
  import type { FC } from 'react';
2
2
  import type { VariantProps } from 'tailwind-variants';
3
3
 
4
- import { useMemo } from 'react';
5
-
6
- import type { CommonProps } from '@twintag-form/types';
4
+ import { useFormContext } from 'react-hook-form';
7
5
 
8
6
  import { Label } from '@twintag-form/components';
9
- import { simpleStyle } from '@twintag-form/styles';
7
+ import { type CommonProps } from './__props';
8
+ import { simpleStyle } from './__styles';
10
9
 
11
10
  type Props = CommonProps<VariantProps<typeof simpleStyle>['variant']>;
12
11
 
13
- const Textarea: FC<Props> = ({ useForm, label, bind, options }) => {
14
- const { container, span, input } = useMemo(() => {
15
- if (options?.variant) return simpleStyle({ variant: options.variant });
16
- return simpleStyle();
17
- }, []);
12
+ const Textarea: FC<Props> = ({ label, bind, options }) => {
13
+ const { register } = useFormContext();
14
+
15
+ const { container, span, input } = simpleStyle({ variant: options?.variant });
18
16
 
19
17
  return (
20
18
  <label className={container()}>
@@ -29,7 +27,7 @@ const Textarea: FC<Props> = ({ useForm, label, bind, options }) => {
29
27
  <textarea
30
28
  className={input()}
31
29
  placeholder={options?.placeholder || 'Write here...'}
32
- {...useForm!.register(bind, {
30
+ {...register(bind, {
33
31
  required: options?.optionalField ? false : `${label} is required`,
34
32
  })}
35
33
  />
@@ -1,34 +1,33 @@
1
1
  import type { FC } from 'react';
2
2
  import type { VariantProps } from 'tailwind-variants';
3
3
 
4
- import { useMemo } from 'react';
5
- import { useController } from 'react-hook-form';
4
+ import { useController, useFormContext } from 'react-hook-form';
6
5
  import * as Switch from '@radix-ui/react-switch';
7
6
 
8
- import type { CommonProps } from '@twintag-form/types';
9
-
10
7
  import { Label } from '@twintag-form/components';
11
- import { toggleStyle } from '@twintag-form/styles';
8
+ import { type CommonProps } from './__props';
9
+ import { toggleStyle } from './__styles';
12
10
 
13
11
  type Props = CommonProps<VariantProps<typeof toggleStyle>['variant']>;
14
12
 
15
- const Toggle: FC<Props> = ({ useForm, label, bind, options }) => {
16
- const { container, span, input, thumb } = useMemo(() => {
17
- if (options?.variant) return toggleStyle({ variant: options.variant });
18
- return toggleStyle();
19
- }, []);
13
+ const Toggle: FC<Props> = ({ label, bind, options }) => {
14
+ const { control } = useFormContext();
20
15
 
21
16
  const {
22
17
  field: { ref, value, onChange },
23
18
  } = useController({
19
+ control,
24
20
  name: bind,
25
- control: useForm ? useForm.control : undefined,
26
21
  defaultValue: false,
27
22
  rules: {
28
23
  required: options?.optionalField ? false : `${label} is required`,
29
24
  },
30
25
  });
31
26
 
27
+ const { container, span, input, thumb } = toggleStyle({
28
+ variant: options?.variant,
29
+ });
30
+
32
31
  return (
33
32
  <label className={container()}>
34
33
  {label ? (
@@ -15,7 +15,8 @@ const Label: FC<Props> = ({ className, required, children }) => {
15
15
 
16
16
  return (
17
17
  <span className={style}>
18
- {children} {required ? '*' : ''}
18
+ {children}{' '}
19
+ {required ? <span className='text-xs text-red-500'>*</span> : <></>}
19
20
  </span>
20
21
  );
21
22
  };
@@ -1,6 +1,4 @@
1
- import Form from './Form';
2
- import Input from './Input';
3
- import Label from './Label';
4
- import Category from './Category';
5
-
6
- export { Form, Input, Label, Category };
1
+ export { default as Form } from './Form';
2
+ export { default as Input } from './Input';
3
+ export { default as Label } from './Label';
4
+ export { default as Category } from './Category';