zormy 0.0.1 → 0.0.11

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 (239) hide show
  1. package/AI_SPEC.md +224 -0
  2. package/README.md +126 -21
  3. package/dist/src/components/Form.cjs +35 -0
  4. package/dist/src/components/Form.d.cts +45 -0
  5. package/dist/src/components/Form.d.cts.map +1 -0
  6. package/dist/src/components/Form.d.ts +45 -0
  7. package/dist/src/components/Form.d.ts.map +1 -0
  8. package/dist/src/components/Form.js +31 -0
  9. package/dist/src/components/Step.cjs +17 -0
  10. package/dist/src/components/Step.d.cts +16 -0
  11. package/dist/src/components/Step.d.cts.map +1 -0
  12. package/dist/src/components/Step.d.ts +16 -0
  13. package/dist/src/components/Step.d.ts.map +1 -0
  14. package/dist/src/components/Step.js +14 -0
  15. package/dist/src/components/Wizard.cjs +36 -0
  16. package/dist/src/components/Wizard.d.cts +45 -0
  17. package/dist/src/components/Wizard.d.cts.map +1 -0
  18. package/dist/src/components/Wizard.d.ts +45 -0
  19. package/dist/src/components/Wizard.d.ts.map +1 -0
  20. package/dist/src/components/Wizard.js +32 -0
  21. package/dist/src/fields/dependency/extractor.cjs +90 -0
  22. package/dist/src/fields/dependency/extractor.d.cts +16 -0
  23. package/dist/src/fields/dependency/extractor.d.cts.map +1 -0
  24. package/dist/src/fields/dependency/extractor.d.ts +16 -0
  25. package/dist/src/fields/dependency/extractor.d.ts.map +1 -0
  26. package/dist/src/fields/dependency/extractor.js +87 -0
  27. package/dist/src/fields/dependency/types/dependency.cjs +2 -0
  28. package/dist/src/fields/dependency/types/dependency.d.cts +37 -0
  29. package/dist/src/fields/dependency/types/dependency.d.cts.map +1 -0
  30. package/dist/src/fields/dependency/types/dependency.d.ts +37 -0
  31. package/dist/src/fields/dependency/types/dependency.d.ts.map +1 -0
  32. package/dist/src/fields/dependency/types/dependency.js +1 -0
  33. package/dist/src/fields/dependency/types/extractors.cjs +2 -0
  34. package/dist/src/fields/dependency/types/extractors.d.cts +116 -0
  35. package/dist/src/fields/dependency/types/extractors.d.cts.map +1 -0
  36. package/dist/src/fields/dependency/types/extractors.d.ts +116 -0
  37. package/dist/src/fields/dependency/types/extractors.d.ts.map +1 -0
  38. package/dist/src/fields/dependency/types/extractors.js +1 -0
  39. package/dist/src/fields/field/builder/builder.cjs +86 -0
  40. package/dist/src/fields/field/builder/builder.d.cts +41 -0
  41. package/dist/src/fields/field/builder/builder.d.cts.map +1 -0
  42. package/dist/src/fields/field/builder/builder.d.ts +41 -0
  43. package/dist/src/fields/field/builder/builder.d.ts.map +1 -0
  44. package/dist/src/fields/field/builder/builder.js +82 -0
  45. package/dist/src/fields/field/builder/factory.cjs +115 -0
  46. package/dist/src/fields/field/builder/factory.d.cts +63 -0
  47. package/dist/src/fields/field/builder/factory.d.cts.map +1 -0
  48. package/dist/src/fields/field/builder/factory.d.ts +63 -0
  49. package/dist/src/fields/field/builder/factory.d.ts.map +1 -0
  50. package/dist/src/fields/field/builder/factory.js +112 -0
  51. package/dist/src/fields/field/builder/handlers.cjs +2 -0
  52. package/dist/src/fields/field/builder/handlers.d.cts +38 -0
  53. package/dist/src/fields/field/builder/handlers.d.cts.map +1 -0
  54. package/dist/src/fields/field/builder/handlers.d.ts +38 -0
  55. package/dist/src/fields/field/builder/handlers.d.ts.map +1 -0
  56. package/dist/src/fields/field/builder/handlers.js +1 -0
  57. package/dist/src/fields/field/builder/helpers.cjs +153 -0
  58. package/dist/src/fields/field/builder/helpers.d.cts +89 -0
  59. package/dist/src/fields/field/builder/helpers.d.cts.map +1 -0
  60. package/dist/src/fields/field/builder/helpers.d.ts +89 -0
  61. package/dist/src/fields/field/builder/helpers.d.ts.map +1 -0
  62. package/dist/src/fields/field/builder/helpers.js +148 -0
  63. package/dist/src/fields/field/hooks/use-field.cjs +89 -0
  64. package/dist/src/fields/field/hooks/use-field.d.cts +106 -0
  65. package/dist/src/fields/field/hooks/use-field.d.cts.map +1 -0
  66. package/dist/src/fields/field/hooks/use-field.d.ts +106 -0
  67. package/dist/src/fields/field/hooks/use-field.d.ts.map +1 -0
  68. package/dist/src/fields/field/hooks/use-field.js +85 -0
  69. package/dist/src/fields/field/types/builder.cjs +2 -0
  70. package/dist/src/fields/field/types/builder.d.cts +195 -0
  71. package/dist/src/fields/field/types/builder.d.cts.map +1 -0
  72. package/dist/src/fields/field/types/builder.d.ts +195 -0
  73. package/dist/src/fields/field/types/builder.d.ts.map +1 -0
  74. package/dist/src/fields/field/types/builder.js +1 -0
  75. package/dist/src/fields/field/types/extractors.cjs +2 -0
  76. package/dist/src/fields/field/types/extractors.d.cts +82 -0
  77. package/dist/src/fields/field/types/extractors.d.cts.map +1 -0
  78. package/dist/src/fields/field/types/extractors.d.ts +82 -0
  79. package/dist/src/fields/field/types/extractors.d.ts.map +1 -0
  80. package/dist/src/fields/field/types/extractors.js +1 -0
  81. package/dist/src/fields/field/types/field.cjs +2 -0
  82. package/dist/src/fields/field/types/field.d.cts +119 -0
  83. package/dist/src/fields/field/types/field.d.cts.map +1 -0
  84. package/dist/src/fields/field/types/field.d.ts +119 -0
  85. package/dist/src/fields/field/types/field.d.ts.map +1 -0
  86. package/dist/src/fields/field/types/field.js +1 -0
  87. package/dist/src/fields/index.cjs +22 -0
  88. package/dist/src/fields/index.d.cts +19 -0
  89. package/dist/src/fields/index.d.cts.map +1 -0
  90. package/dist/src/fields/index.d.ts +19 -0
  91. package/dist/src/fields/index.d.ts.map +1 -0
  92. package/dist/src/fields/index.js +15 -0
  93. package/dist/src/index.cjs +50 -0
  94. package/dist/src/index.d.cts +26 -0
  95. package/dist/src/index.d.cts.map +1 -0
  96. package/dist/src/index.d.ts +26 -0
  97. package/dist/src/index.d.ts.map +1 -0
  98. package/dist/src/index.js +23 -0
  99. package/dist/src/integrations/react-hook-form.cjs +5 -0
  100. package/dist/src/integrations/react-hook-form.d.cts +3 -0
  101. package/dist/src/integrations/react-hook-form.d.cts.map +1 -0
  102. package/dist/src/integrations/react-hook-form.d.ts +3 -0
  103. package/dist/src/integrations/react-hook-form.d.ts.map +1 -0
  104. package/dist/src/integrations/react-hook-form.js +1 -0
  105. package/dist/src/resolver/helpers/nested-objects.cjs +239 -0
  106. package/dist/src/resolver/helpers/nested-objects.d.cts +89 -0
  107. package/dist/src/resolver/helpers/nested-objects.d.cts.map +1 -0
  108. package/dist/src/resolver/helpers/nested-objects.d.ts +89 -0
  109. package/dist/src/resolver/helpers/nested-objects.d.ts.map +1 -0
  110. package/dist/src/resolver/helpers/nested-objects.js +231 -0
  111. package/dist/src/resolver/helpers/shape-to-zod-schema.cjs +28 -0
  112. package/dist/src/resolver/helpers/shape-to-zod-schema.d.cts +20 -0
  113. package/dist/src/resolver/helpers/shape-to-zod-schema.d.cts.map +1 -0
  114. package/dist/src/resolver/helpers/shape-to-zod-schema.d.ts +20 -0
  115. package/dist/src/resolver/helpers/shape-to-zod-schema.d.ts.map +1 -0
  116. package/dist/src/resolver/helpers/shape-to-zod-schema.js +25 -0
  117. package/dist/src/resolver/resolver.cjs +40 -0
  118. package/dist/src/resolver/resolver.d.cts +40 -0
  119. package/dist/src/resolver/resolver.d.cts.map +1 -0
  120. package/dist/src/resolver/resolver.d.ts +40 -0
  121. package/dist/src/resolver/resolver.d.ts.map +1 -0
  122. package/dist/src/resolver/resolver.js +37 -0
  123. package/dist/src/resolver/types/nested-helpers.cjs +2 -0
  124. package/dist/src/resolver/types/nested-helpers.d.cts +109 -0
  125. package/dist/src/resolver/types/nested-helpers.d.cts.map +1 -0
  126. package/dist/src/resolver/types/nested-helpers.d.ts +109 -0
  127. package/dist/src/resolver/types/nested-helpers.d.ts.map +1 -0
  128. package/dist/src/resolver/types/nested-helpers.js +1 -0
  129. package/dist/src/types/dot-notation.cjs +2 -0
  130. package/dist/src/types/dot-notation.d.cts +8 -0
  131. package/dist/src/types/dot-notation.d.cts.map +1 -0
  132. package/dist/src/types/dot-notation.d.ts +8 -0
  133. package/dist/src/types/dot-notation.d.ts.map +1 -0
  134. package/dist/src/types/dot-notation.js +1 -0
  135. package/dist/src/types/object.cjs +2 -0
  136. package/dist/src/types/object.d.cts +18 -0
  137. package/dist/src/types/object.d.cts.map +1 -0
  138. package/dist/src/types/object.d.ts +18 -0
  139. package/dist/src/types/object.d.ts.map +1 -0
  140. package/dist/src/types/object.js +1 -0
  141. package/dist/src/wizards/step/hooks/use-step-machine.cjs +155 -0
  142. package/dist/src/wizards/step/hooks/use-step-machine.d.cts +104 -0
  143. package/dist/src/wizards/step/hooks/use-step-machine.d.cts.map +1 -0
  144. package/dist/src/wizards/step/hooks/use-step-machine.d.ts +104 -0
  145. package/dist/src/wizards/step/hooks/use-step-machine.d.ts.map +1 -0
  146. package/dist/src/wizards/step/hooks/use-step-machine.js +151 -0
  147. package/dist/src/wizards/step/types/step.cjs +2 -0
  148. package/dist/src/wizards/step/types/step.d.cts +59 -0
  149. package/dist/src/wizards/step/types/step.d.cts.map +1 -0
  150. package/dist/src/wizards/step/types/step.d.ts +59 -0
  151. package/dist/src/wizards/step/types/step.d.ts.map +1 -0
  152. package/dist/src/wizards/step/types/step.js +1 -0
  153. package/dist/src/wizards/step/utils/step-effects.cjs +73 -0
  154. package/dist/src/wizards/step/utils/step-effects.d.cts +54 -0
  155. package/dist/src/wizards/step/utils/step-effects.d.cts.map +1 -0
  156. package/dist/src/wizards/step/utils/step-effects.d.ts +54 -0
  157. package/dist/src/wizards/step/utils/step-effects.d.ts.map +1 -0
  158. package/dist/src/wizards/step/utils/step-effects.js +68 -0
  159. package/dist/src/wizards/step/utils/step.cjs +326 -0
  160. package/dist/src/wizards/step/utils/step.d.cts +119 -0
  161. package/dist/src/wizards/step/utils/step.d.cts.map +1 -0
  162. package/dist/src/wizards/step/utils/step.d.ts +119 -0
  163. package/dist/src/wizards/step/utils/step.d.ts.map +1 -0
  164. package/dist/src/wizards/step/utils/step.js +312 -0
  165. package/dist/src/wizards/wizard/builder/components.cjs +75 -0
  166. package/dist/src/wizards/wizard/builder/components.d.cts +106 -0
  167. package/dist/src/wizards/wizard/builder/components.d.cts.map +1 -0
  168. package/dist/src/wizards/wizard/builder/components.d.ts +106 -0
  169. package/dist/src/wizards/wizard/builder/components.d.ts.map +1 -0
  170. package/dist/src/wizards/wizard/builder/components.js +72 -0
  171. package/dist/src/wizards/wizard/builder/config.cjs +33 -0
  172. package/dist/src/wizards/wizard/builder/config.d.cts +35 -0
  173. package/dist/src/wizards/wizard/builder/config.d.cts.map +1 -0
  174. package/dist/src/wizards/wizard/builder/config.d.ts +35 -0
  175. package/dist/src/wizards/wizard/builder/config.d.ts.map +1 -0
  176. package/dist/src/wizards/wizard/builder/config.js +30 -0
  177. package/dist/src/wizards/wizard/builder/helpers.cjs +145 -0
  178. package/dist/src/wizards/wizard/builder/helpers.d.cts +85 -0
  179. package/dist/src/wizards/wizard/builder/helpers.d.cts.map +1 -0
  180. package/dist/src/wizards/wizard/builder/helpers.d.ts +85 -0
  181. package/dist/src/wizards/wizard/builder/helpers.d.ts.map +1 -0
  182. package/dist/src/wizards/wizard/builder/helpers.js +138 -0
  183. package/dist/src/wizards/wizard/context.cjs +77 -0
  184. package/dist/src/wizards/wizard/context.d.cts +84 -0
  185. package/dist/src/wizards/wizard/context.d.cts.map +1 -0
  186. package/dist/src/wizards/wizard/context.d.ts +84 -0
  187. package/dist/src/wizards/wizard/context.d.ts.map +1 -0
  188. package/dist/src/wizards/wizard/context.js +72 -0
  189. package/dist/src/wizards/wizard/hooks/use-auto-save.cjs +175 -0
  190. package/dist/src/wizards/wizard/hooks/use-auto-save.d.cts +30 -0
  191. package/dist/src/wizards/wizard/hooks/use-auto-save.d.cts.map +1 -0
  192. package/dist/src/wizards/wizard/hooks/use-auto-save.d.ts +30 -0
  193. package/dist/src/wizards/wizard/hooks/use-auto-save.d.ts.map +1 -0
  194. package/dist/src/wizards/wizard/hooks/use-auto-save.js +171 -0
  195. package/dist/src/wizards/wizard/hooks/use-wizard-form.cjs +490 -0
  196. package/dist/src/wizards/wizard/hooks/use-wizard-form.d.cts +39 -0
  197. package/dist/src/wizards/wizard/hooks/use-wizard-form.d.cts.map +1 -0
  198. package/dist/src/wizards/wizard/hooks/use-wizard-form.d.ts +39 -0
  199. package/dist/src/wizards/wizard/hooks/use-wizard-form.d.ts.map +1 -0
  200. package/dist/src/wizards/wizard/hooks/use-wizard-form.js +486 -0
  201. package/dist/src/wizards/wizard/hooks/use-wizard.cjs +341 -0
  202. package/dist/src/wizards/wizard/hooks/use-wizard.d.cts +112 -0
  203. package/dist/src/wizards/wizard/hooks/use-wizard.d.cts.map +1 -0
  204. package/dist/src/wizards/wizard/hooks/use-wizard.d.ts +112 -0
  205. package/dist/src/wizards/wizard/hooks/use-wizard.d.ts.map +1 -0
  206. package/dist/src/wizards/wizard/hooks/use-wizard.js +337 -0
  207. package/dist/src/wizards/wizard/types/extractors.cjs +2 -0
  208. package/dist/src/wizards/wizard/types/extractors.d.cts +67 -0
  209. package/dist/src/wizards/wizard/types/extractors.d.cts.map +1 -0
  210. package/dist/src/wizards/wizard/types/extractors.d.ts +67 -0
  211. package/dist/src/wizards/wizard/types/extractors.d.ts.map +1 -0
  212. package/dist/src/wizards/wizard/types/extractors.js +1 -0
  213. package/dist/src/wizards/wizard/types/hooks.cjs +8 -0
  214. package/dist/src/wizards/wizard/types/hooks.d.cts +136 -0
  215. package/dist/src/wizards/wizard/types/hooks.d.cts.map +1 -0
  216. package/dist/src/wizards/wizard/types/hooks.d.ts +136 -0
  217. package/dist/src/wizards/wizard/types/hooks.d.ts.map +1 -0
  218. package/dist/src/wizards/wizard/types/hooks.js +7 -0
  219. package/dist/src/wizards/wizard/types/wizard.cjs +32 -0
  220. package/dist/src/wizards/wizard/types/wizard.d.cts +79 -0
  221. package/dist/src/wizards/wizard/types/wizard.d.cts.map +1 -0
  222. package/dist/src/wizards/wizard/types/wizard.d.ts +79 -0
  223. package/dist/src/wizards/wizard/types/wizard.d.ts.map +1 -0
  224. package/dist/src/wizards/wizard/types/wizard.js +31 -0
  225. package/dist/src/wizards/wizard/utils/navigation.cjs +32 -0
  226. package/dist/src/wizards/wizard/utils/navigation.d.cts +43 -0
  227. package/dist/src/wizards/wizard/utils/navigation.d.cts.map +1 -0
  228. package/dist/src/wizards/wizard/utils/navigation.d.ts +43 -0
  229. package/dist/src/wizards/wizard/utils/navigation.d.ts.map +1 -0
  230. package/dist/src/wizards/wizard/utils/navigation.js +29 -0
  231. package/dist/src/wizards/wizard/utils/resolver-helpers.cjs +150 -0
  232. package/dist/src/wizards/wizard/utils/resolver-helpers.d.cts +35 -0
  233. package/dist/src/wizards/wizard/utils/resolver-helpers.d.cts.map +1 -0
  234. package/dist/src/wizards/wizard/utils/resolver-helpers.d.ts +35 -0
  235. package/dist/src/wizards/wizard/utils/resolver-helpers.d.ts.map +1 -0
  236. package/dist/src/wizards/wizard/utils/resolver-helpers.js +144 -0
  237. package/package.json +59 -31
  238. package/LICENSE +0 -15
  239. package/index.js +0 -1
package/AI_SPEC.md ADDED
@@ -0,0 +1,224 @@
1
+ # Zormy — AI Spec
2
+
3
+ > Especificação para assistentes de IA: como usar o pacote **zormy** em projetos React.
4
+
5
+ ## O que é
6
+
7
+ **Zormy** é uma biblioteca para formulários tipados e reutilizáveis em React. Combina:
8
+
9
+ - **React Hook Form** — controle de formulário
10
+ - **Zod** — validação e schemas
11
+ - **TypeScript** — inferência de tipos end-to-end
12
+
13
+ Conceitos principais:
14
+
15
+ - **Campos reutilizáveis**: criados com `field("key")` ou `abstractField()`, com `.schema()` e `.render()`.
16
+ - **Resolver**: `formyResolver({ fields: [...] })` monta o schema Zod a partir dos campos e integra com react-hook-form.
17
+ - **Form**: componente `<Form methods={...}>` que fornece contexto (FormProvider).
18
+ - **Wizards**: fluxos multi-step com `createWizardConfig`, `createWizardComponents` e `useWizard`.
19
+
20
+ ---
21
+
22
+ ## Instalação e dependências
23
+
24
+ ```bash
25
+ pnpm add zormy zod react-hook-form @hookform/resolvers
26
+ ```
27
+
28
+ Peer dependencies: `react` (^18), `react-hook-form` (^7.71.1), `zod` (^3.25.28), `@hookform/resolvers` (^5.2.2).
29
+
30
+ ---
31
+
32
+ ## API principal (import de `zormy`)
33
+
34
+ | Exportação | Uso |
35
+ |------------|-----|
36
+ | `field(key)` | Builder para campo com chave fixa (ex: `"name"`, `"user.email"`) |
37
+ | `abstractField()` | Builder para campo sem chave; usar `.extend({ key: "..." })` para obter um campo concreto |
38
+ | `formyResolver({ fields })` | Resolver para `useForm`; recebe array de campos e infere tipo do formulário |
39
+ | `Form` | `<Form methods={form}>` — fornece contexto do formulário (e opcionalmente `<form>`) |
40
+ | `useForm` | Re-export do react-hook-form (para tipagem consistente) |
41
+ | `createWizardConfig({ steps, fields, shouldIncludeStep? })` | Configuração do wizard (steps e campos por step) |
42
+ | `createWizardComponents(config)` | Retorna `{ Wizard, Step }` tipados |
43
+ | `useWizard(config & { defaultValues, onSubmit?, ... })` | Hook do wizard (form + navegação entre steps) |
44
+ | `useWizardContext` | Acesso ao contexto do wizard |
45
+ | `useAutoSaveContext`, `AutoSaveStatus` | Auto-save no wizard |
46
+ | `Controller`, `SubmitHandler` | Re-export do react-hook-form |
47
+
48
+ Tipos úteis: `FieldKey`, `FieldsToObject`, `FieldValue`.
49
+
50
+ ---
51
+
52
+ ## Padrão: formulário simples
53
+
54
+ 1. Definir campos com `field("key").schema(zodSchema).render(...)`.
55
+ 2. Criar o form com `useForm({ resolver: formyResolver({ fields: [...] }), defaultValues })`.
56
+ 3. Envolver a UI em `<Form methods={form}>` e renderizar os campos como componentes.
57
+
58
+ ```tsx
59
+ import { z } from "zod";
60
+ import { field, Form, formyResolver, useForm } from "zormy";
61
+
62
+ const NameField = field("name")
63
+ .schema(z.string().min(3, "Mín. 3 caracteres"))
64
+ .render(({ register, fieldState }) => (
65
+ <div>
66
+ <input {...register()} />
67
+ {fieldState.error && <span>{fieldState.error.message}</span>}
68
+ </div>
69
+ ));
70
+
71
+ function MyForm() {
72
+ const form = useForm({
73
+ resolver: formyResolver({ fields: [NameField] }),
74
+ defaultValues: { name: "" },
75
+ });
76
+ return (
77
+ <Form methods={form} onSubmit={form.handleSubmit((data) => console.log(data))}>
78
+ <NameField />
79
+ <button type="submit">Enviar</button>
80
+ </Form>
81
+ );
82
+ }
83
+ ```
84
+
85
+ - **Importante**: o `resolver` deve usar exatamente os campos que serão renderizados; `defaultValues` deve cobrir todas as chaves dos campos (incluindo aninhadas, se houver).
86
+ - No `render`, use `register()` sem argumentos para usar a chave do campo; para sobrescrever: `register({ name: "outra.chave" })`.
87
+
88
+ ---
89
+
90
+ ## Campos aninhados (dot-notation)
91
+
92
+ Chaves com ponto são suportadas: o resolver monta um schema aninhado e os valores são acessados como `address.street`, etc.
93
+
94
+ ```tsx
95
+ const StreetField = field("address.street")
96
+ .schema(z.string().min(1))
97
+ .render(({ register }) => <input {...register()} />);
98
+ // defaultValues: { address: { street: "" } }
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Campos com dependências (dinâmicos)
104
+
105
+ Use `.dependsOn(OutroCampo, ...)` e depois `.schema()` com função que recebe `formValues` para schema condicional.
106
+
107
+ ```tsx
108
+ const PhoneField = field("phone")
109
+ .dependsOn(NameField)
110
+ .schema((formValues) => {
111
+ const name = formValues?.name;
112
+ return name?.length ? z.string().min(10, "Telefone obrigatório") : z.string().optional();
113
+ })
114
+ .render(({ register, fieldState, getValues }) => {
115
+ const name = getValues("name");
116
+ const required = Boolean(name?.length);
117
+ return <input {...register()} required={required} />;
118
+ });
119
+ ```
120
+
121
+ O array passado para `formyResolver({ fields })` deve incluir todos os campos usados (incluindo os de `dependsOn`).
122
+
123
+ ---
124
+
125
+ ## Campo abstrato (template)
126
+
127
+ Use quando vários campos compartilham schema e UI, mudando só a chave.
128
+
129
+ ```tsx
130
+ const BaseText = abstractField()
131
+ .schema(z.string().min(3))
132
+ .render(({ register, fieldState }) => (
133
+ <div>
134
+ <input {...register()} />
135
+ {fieldState.error && <span>{fieldState.error.message}</span>}
136
+ </div>
137
+ ));
138
+
139
+ const NameField = BaseText.extend({ key: "name" });
140
+ const EmailField = BaseText.extend({ key: "email" });
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Wizard multi-step
146
+
147
+ 1. Definir `steps` (array de strings literais, ex: `["personal", "contact"] as const`).
148
+ 2. Mapear cada step para um array de campos em `fields`: `{ personal: [NameField], contact: [EmailField] }`.
149
+ 3. `createWizardConfig({ steps, fields, shouldIncludeStep? })`.
150
+ 4. `createWizardComponents(config)` → `{ Wizard, Step }`.
151
+ 5. `useWizard({ ...config, defaultValues, onSubmit?, initialStep?, mode?, autoSave?, ... })`.
152
+ 6. Renderizar: `<Wizard wizard={wizard}>` e dentro `<Step step="personal">` etc.; usar `wizard.nextStep`, `wizard.prevStep` para navegação.
153
+
154
+ ```tsx
155
+ const config = createWizardConfig({
156
+ steps: ["personal", "contact"] as const,
157
+ fields: { personal: [NameField], contact: [EmailField] },
158
+ });
159
+ const { Wizard, Step } = createWizardComponents(config);
160
+
161
+ function MyWizard() {
162
+ const wizard = useWizard({
163
+ ...config,
164
+ defaultValues: { name: "", email: "" },
165
+ onSubmit: (data) => console.log(data),
166
+ });
167
+ return (
168
+ <Wizard wizard={wizard}>
169
+ <Step step="personal">
170
+ <NameField />
171
+ <button type="button" onClick={wizard.nextStep}>Próximo</button>
172
+ </Step>
173
+ <Step step="contact">
174
+ <EmailField />
175
+ <button type="button" onClick={wizard.prevStep}>Voltar</button>
176
+ <button type="submit">Enviar</button>
177
+ </Step>
178
+ </Wizard>
179
+ );
180
+ }
181
+ ```
182
+
183
+ - `defaultValues` deve cobrir todas as chaves de todos os campos de todos os steps.
184
+ - Steps condicionais: use `shouldIncludeStep: (step, formValues) => boolean` em `createWizardConfig`.
185
+
186
+ ---
187
+
188
+ ## Form sem elemento `<form>`
189
+
190
+ Use `<Form methods={form} contextOnly>` e um único filho que receberá **apenas o contexto** (FormProvider). Props HTML passadas ao `Form` **não** são repassadas automaticamente ao filho (ex.: componente customizado ou Radix Slot).
191
+
192
+ ---
193
+
194
+ ## O que evitar
195
+
196
+ - Não passar para `formyResolver` campos que não serão renderizados no formulário (ou o tipo e o schema podem ficar inconsistentes).
197
+ - Não misturar chaves flat e aninhadas de forma inconsistente em `defaultValues` (ex.: campo `"user.email"` exige `defaultValues.user.email`).
198
+ - Em wizards, não esquecer de incluir todos os campos de todos os steps em `defaultValues`.
199
+ - Para campos com `dependsOn`, sempre incluir os campos dependentes no array `fields` do resolver (e no wizard, no step correto).
200
+
201
+ ---
202
+
203
+ ## Estrutura de testes (manutenção)
204
+
205
+ Em `packages/zormy/__tests__/`:
206
+
207
+ - **`unit/`** — testes unitários por módulo: `unit/fields/`, `unit/wizard/`, `unit/utils/`, `unit/resolvers/`.
208
+ - **`types/`** — testes de tipo (`.test-d.ts`): `types/fields/`, `types/wizard/`.
209
+ - **`performance/`** — benchmarks e testes de re-render (mantido como está).
210
+ - **`integration/`** — reservado para testes end-to-end futuros (vários módulos).
211
+
212
+ Comandos: `pnpm test`, `pnpm test:typecheck`, `pnpm test:bench`.
213
+
214
+ ---
215
+
216
+ ## Resumo para geração de código
217
+
218
+ 1. **Formulário simples**: `field("key").schema(z...).render(({ register, fieldState }) => ...)` → `formyResolver({ fields: [...] })` → `useForm` → `<Form methods={form}>` + campos.
219
+ 2. **Aninhado**: chave `"a.b.c"` e `defaultValues: { a: { b: { c: "" } } }`.
220
+ 3. **Condicional**: `.dependsOn(OutroCampo).schema((formValues) => z...)` e incluir dependentes em `fields`.
221
+ 4. **Template**: `abstractField().schema(...).render(...)` e `.extend({ key: "..." })`.
222
+ 5. **Wizard**: `createWizardConfig` → `createWizardComponents` → `useWizard` → `<Wizard>` + `<Step step="...">` e botões com `nextStep`/`prevStep`.
223
+
224
+ Versão do pacote: ver `package.json`. Requer React 18+, TypeScript 5+ recomendado.
package/README.md CHANGED
@@ -1,21 +1,126 @@
1
- # zormy
2
-
3
- > Initial placeholder package - currently under development
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install zormy
9
- ```
10
-
11
- ## Usage
12
-
13
- ```javascript
14
- const zormy = require('zormy');
15
-
16
- // Coming soon...
17
- ```
18
-
19
- ## License
20
-
21
- ISC
1
+ # Zormy
2
+
3
+ Sistema de formulários tipados e reutilizáveis para React, com validação Zod, campos aninhados e wizards multi-step.
4
+
5
+ ## Instalação
6
+
7
+ ```bash
8
+ pnpm add zormy zod react-hook-form @hookform/resolvers
9
+ ```
10
+
11
+ Ou com npm/yarn:
12
+
13
+ ```bash
14
+ npm install zormy zod react-hook-form @hookform/resolvers
15
+ ```
16
+
17
+ ## Uso rápido
18
+
19
+ ### Formulário simples
20
+
21
+ ```tsx
22
+ import { field, Form, formyResolver, useForm } from "zormy";
23
+ import { z } from "zod";
24
+
25
+ const NameField = field("name")
26
+ .schema(z.string().min(3, "Mínimo 3 caracteres"))
27
+ .render(({ register, fieldState }) => (
28
+ <div>
29
+ <input {...register()} />
30
+ {fieldState.error && <span>{fieldState.error.message}</span>}
31
+ </div>
32
+ ));
33
+
34
+ function MyForm() {
35
+ const form = useForm({
36
+ resolver: formyResolver({ fields: [NameField] }),
37
+ defaultValues: { name: "" },
38
+ mode: "onChange", // ou "onBlur" | "onSubmit" | "onTouched" | "all"
39
+ });
40
+
41
+ return (
42
+ <Form methods={form} onSubmit={form.handleSubmit((data) => console.log(data))}>
43
+ <NameField />
44
+ <button type="submit">Enviar</button>
45
+ </Form>
46
+ );
47
+ }
48
+ ```
49
+
50
+ ### Wizard multi-step
51
+
52
+ ```tsx
53
+ import { createWizardConfig, createWizardComponents, useWizard, field } from "zormy";
54
+ import { z } from "zod";
55
+
56
+ const NameField = field("name").schema(z.string().min(3)).render(({ register, fieldState }) => (
57
+ <div>
58
+ <input {...register()} />
59
+ {fieldState.error && <span>{fieldState.error.message}</span>}
60
+ </div>
61
+ ));
62
+
63
+ const EmailField = field("email").schema(z.string().email()).render(({ register, fieldState }) => (
64
+ <div>
65
+ <input type="email" {...register()} />
66
+ {fieldState.error && <span>{fieldState.error.message}</span>}
67
+ </div>
68
+ ));
69
+
70
+ const config = createWizardConfig({
71
+ steps: ["personal", "contact"] as const,
72
+ fields: {
73
+ personal: [NameField],
74
+ contact: [EmailField],
75
+ },
76
+ });
77
+
78
+ const { Wizard, Step } = createWizardComponents(config);
79
+
80
+ function MyWizard() {
81
+ const wizard = useWizard({
82
+ ...config,
83
+ defaultValues: { name: "", email: "" },
84
+ mode: "onChange", // opcional: modo de validação do wizard
85
+ onSubmit: (data) => console.log(data),
86
+ });
87
+
88
+ return (
89
+ <Wizard methods={wizard} onSubmit={wizard.handleSubmit()}>
90
+ <Step step="personal"><NameField /></Step>
91
+ <Step step="contact"><EmailField /></Step>
92
+ <div>
93
+ {!wizard.isFirstStep && <button type="button" onClick={wizard.back}>Voltar</button>}
94
+ {wizard.isLastStep ? (
95
+ <button type="submit">Finalizar</button>
96
+ ) : (
97
+ <button type="button" onClick={() => void wizard.next()}>Próximo</button>
98
+ )}
99
+ </div>
100
+ </Wizard>
101
+ );
102
+ }
103
+ ```
104
+
105
+ ## Recursos
106
+
107
+ - **TypeScript**: inferência de tipos a partir dos campos e do Zod
108
+ - **Validação**: schemas Zod estáticos ou dinâmicos (por valores do formulário)
109
+ - **Campos reutilizáveis**: `field("key")` e `abstractField()` com `.extend()`
110
+ - **Wizards**: steps, validação por etapa, steps condicionais, auto-save opcional
111
+ - **Resolver**: `formyResolver({ fields })` com suporte a chaves aninhadas (`"user.email"`)
112
+
113
+ ## Documentação
114
+
115
+ Para guias completos, exemplos e API reference, consulte a [documentação do projeto](https://github.com/your-org/zormy) (ou o site de docs quando disponível).
116
+
117
+ ## Peer dependencies
118
+
119
+ - `react` (catalog)
120
+ - `react-hook-form` ^7.71.1
121
+ - `zod` ^3.25.28
122
+ - `@hookform/resolvers` ^5.2.2
123
+
124
+ ## Licença
125
+
126
+ Private / conforme o projeto.
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Form = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_hook_form_1 = require("react-hook-form");
6
+ /**
7
+ * Componente de formulário integrado ao react-hook-form.
8
+ *
9
+ * Permite controle flexível do elemento raiz usando a prop `contextOnly`.
10
+ * - Por padrão, renderiza um `<form>`.
11
+ * - Com `contextOnly`, fornece apenas o contexto do formulário e renderiza o filho customizado, repassando as props do formulário para ele (não renderiza `<form>`).
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * // Modo padrão:
16
+ * <Form methods={formMethods}>
17
+ * <input name="foo" />
18
+ * </Form>
19
+ *
20
+ * // Com contextOnly (ex: usando Radix Slot ou wrapper customizado):
21
+ * <Form methods={formMethods} contextOnly>
22
+ * <CustomFormComponent />
23
+ * </Form>
24
+ * ```
25
+ */
26
+ const Form = (props) => {
27
+ const { methods, contextOnly, children, ...formProps } = props;
28
+ if (contextOnly) {
29
+ // Tipagem garante que contextOnly==true implica filhos ReactElement.
30
+ return (0, jsx_runtime_1.jsx)(react_hook_form_1.FormProvider, { ...methods, children: children });
31
+ }
32
+ // Padrão: renderiza <form>
33
+ return ((0, jsx_runtime_1.jsx)(react_hook_form_1.FormProvider, { ...methods, children: (0, jsx_runtime_1.jsx)("form", { ...formProps, children: children }) }));
34
+ };
35
+ exports.Form = Form;
@@ -0,0 +1,45 @@
1
+ import type { ComponentPropsWithoutRef, ReactElement, ReactNode } from "react";
2
+ import type { FieldValues, UseFormReturn } from "react-hook-form";
3
+ /**
4
+ * Props do componente Form.
5
+ *
6
+ * @template TFieldValues - Tipo dos valores do formulário
7
+ * @template TContextOnly - Define se o formulário fornece apenas o contexto (sem envolver em `<form>`). Se true, espera um elemento filho do tipo ReactElement que receberá as props do formulário.
8
+ *
9
+ * @property methods - Instância de UseFormReturn do react-hook-form.
10
+ * @property contextOnly - Se verdadeiro, fornece apenas o contexto do formulário e renderiza o filho customizado **sem envolver em `<form>` e sem repassar props HTML do `Form` para o filho**. Útil para integração com bibliotecas como @radix-ui/react-slot, wrappers customizados, ou cenários avançados de composição.
11
+ */
12
+ export type FormProps<TFieldValues extends FieldValues = FieldValues, TContextOnly extends boolean = false> = TContextOnly extends true ? {
13
+ methods: UseFormReturn<TFieldValues>;
14
+ /** Fornece apenas o contexto do formulário em vez de envolver em um <form>. Veja descrição acima. */
15
+ contextOnly: true;
16
+ /** Elemento filho único que recebe as props do formulário. */
17
+ children: ReactElement;
18
+ } & Omit<ComponentPropsWithoutRef<"form">, "children" | "ref"> : {
19
+ methods: UseFormReturn<TFieldValues>;
20
+ /** Renderiza formulário padrão <form> (valor default). */
21
+ contextOnly?: false | undefined;
22
+ children?: ReactNode;
23
+ } & ComponentPropsWithoutRef<"form">;
24
+ /**
25
+ * Componente de formulário integrado ao react-hook-form.
26
+ *
27
+ * Permite controle flexível do elemento raiz usando a prop `contextOnly`.
28
+ * - Por padrão, renderiza um `<form>`.
29
+ * - Com `contextOnly`, fornece apenas o contexto do formulário e renderiza o filho customizado, repassando as props do formulário para ele (não renderiza `<form>`).
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * // Modo padrão:
34
+ * <Form methods={formMethods}>
35
+ * <input name="foo" />
36
+ * </Form>
37
+ *
38
+ * // Com contextOnly (ex: usando Radix Slot ou wrapper customizado):
39
+ * <Form methods={formMethods} contextOnly>
40
+ * <CustomFormComponent />
41
+ * </Form>
42
+ * ```
43
+ */
44
+ export declare const Form: <TFieldValues extends FieldValues = FieldValues, TContextOnly extends boolean = false>(props: FormProps<TFieldValues, TContextOnly>) => import("react/jsx-runtime").JSX.Element;
45
+ //# sourceMappingURL=Form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../../../src/components/Form.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAElE;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,CACpB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,YAAY,SAAS,OAAO,GAAG,KAAK,IACjC,YAAY,SAAS,IAAI,GAC1B;IACA,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,qGAAqG;IACrG,WAAW,EAAE,IAAI,CAAC;IAClB,8DAA8D;IAC9D,QAAQ,EAAE,YAAY,CAAC;CACvB,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,GAC7D;IACA,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACrB,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,IAAI,GAChB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,YAAY,SAAS,OAAO,GAAG,KAAK,EAEpC,OAAO,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC,4CAc5C,CAAC"}
@@ -0,0 +1,45 @@
1
+ import type { ComponentPropsWithoutRef, ReactElement, ReactNode } from "react";
2
+ import type { FieldValues, UseFormReturn } from "react-hook-form";
3
+ /**
4
+ * Props do componente Form.
5
+ *
6
+ * @template TFieldValues - Tipo dos valores do formulário
7
+ * @template TContextOnly - Define se o formulário fornece apenas o contexto (sem envolver em `<form>`). Se true, espera um elemento filho do tipo ReactElement que receberá as props do formulário.
8
+ *
9
+ * @property methods - Instância de UseFormReturn do react-hook-form.
10
+ * @property contextOnly - Se verdadeiro, fornece apenas o contexto do formulário e renderiza o filho customizado **sem envolver em `<form>` e sem repassar props HTML do `Form` para o filho**. Útil para integração com bibliotecas como @radix-ui/react-slot, wrappers customizados, ou cenários avançados de composição.
11
+ */
12
+ export type FormProps<TFieldValues extends FieldValues = FieldValues, TContextOnly extends boolean = false> = TContextOnly extends true ? {
13
+ methods: UseFormReturn<TFieldValues>;
14
+ /** Fornece apenas o contexto do formulário em vez de envolver em um <form>. Veja descrição acima. */
15
+ contextOnly: true;
16
+ /** Elemento filho único que recebe as props do formulário. */
17
+ children: ReactElement;
18
+ } & Omit<ComponentPropsWithoutRef<"form">, "children" | "ref"> : {
19
+ methods: UseFormReturn<TFieldValues>;
20
+ /** Renderiza formulário padrão <form> (valor default). */
21
+ contextOnly?: false | undefined;
22
+ children?: ReactNode;
23
+ } & ComponentPropsWithoutRef<"form">;
24
+ /**
25
+ * Componente de formulário integrado ao react-hook-form.
26
+ *
27
+ * Permite controle flexível do elemento raiz usando a prop `contextOnly`.
28
+ * - Por padrão, renderiza um `<form>`.
29
+ * - Com `contextOnly`, fornece apenas o contexto do formulário e renderiza o filho customizado, repassando as props do formulário para ele (não renderiza `<form>`).
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * // Modo padrão:
34
+ * <Form methods={formMethods}>
35
+ * <input name="foo" />
36
+ * </Form>
37
+ *
38
+ * // Com contextOnly (ex: usando Radix Slot ou wrapper customizado):
39
+ * <Form methods={formMethods} contextOnly>
40
+ * <CustomFormComponent />
41
+ * </Form>
42
+ * ```
43
+ */
44
+ export declare const Form: <TFieldValues extends FieldValues = FieldValues, TContextOnly extends boolean = false>(props: FormProps<TFieldValues, TContextOnly>) => import("react/jsx-runtime").JSX.Element;
45
+ //# sourceMappingURL=Form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../../../src/components/Form.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAElE;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,CACpB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,YAAY,SAAS,OAAO,GAAG,KAAK,IACjC,YAAY,SAAS,IAAI,GAC1B;IACA,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,qGAAqG;IACrG,WAAW,EAAE,IAAI,CAAC;IAClB,8DAA8D;IAC9D,QAAQ,EAAE,YAAY,CAAC;CACvB,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,GAC7D;IACA,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACrB,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,IAAI,GAChB,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,YAAY,SAAS,OAAO,GAAG,KAAK,EAEpC,OAAO,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC,4CAc5C,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { FormProvider } from "react-hook-form";
3
+ /**
4
+ * Componente de formulário integrado ao react-hook-form.
5
+ *
6
+ * Permite controle flexível do elemento raiz usando a prop `contextOnly`.
7
+ * - Por padrão, renderiza um `<form>`.
8
+ * - Com `contextOnly`, fornece apenas o contexto do formulário e renderiza o filho customizado, repassando as props do formulário para ele (não renderiza `<form>`).
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * // Modo padrão:
13
+ * <Form methods={formMethods}>
14
+ * <input name="foo" />
15
+ * </Form>
16
+ *
17
+ * // Com contextOnly (ex: usando Radix Slot ou wrapper customizado):
18
+ * <Form methods={formMethods} contextOnly>
19
+ * <CustomFormComponent />
20
+ * </Form>
21
+ * ```
22
+ */
23
+ export const Form = (props) => {
24
+ const { methods, contextOnly, children, ...formProps } = props;
25
+ if (contextOnly) {
26
+ // Tipagem garante que contextOnly==true implica filhos ReactElement.
27
+ return _jsx(FormProvider, { ...methods, children: children });
28
+ }
29
+ // Padrão: renderiza <form>
30
+ return (_jsx(FormProvider, { ...methods, children: _jsx("form", { ...formProps, children: children }) }));
31
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Step = Step;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const context_1 = require("../wizards/wizard/context.cjs");
6
+ /**
7
+ * Step para wizard, renderiza somente se ativo e com tipagem dinâmica no as
8
+ */
9
+ function Step(props) {
10
+ const { step, as, children, ...rest } = props;
11
+ const { currentStep } = (0, context_1.useWizardContext)();
12
+ const Component = as || "div";
13
+ if (currentStep !== step) {
14
+ return null;
15
+ }
16
+ return (0, jsx_runtime_1.jsx)(Component, { ...rest, children: children });
17
+ }
@@ -0,0 +1,16 @@
1
+ import type { ComponentPropsWithoutRef, ElementType, ReactNode } from "react";
2
+ /**
3
+ * StepProps tipada para permitir definir dinamicamente o componente raíz
4
+ *
5
+ * @template TAs - Tipo do componente (padrão: 'div')
6
+ */
7
+ export type StepProps<TAs extends ElementType = "div"> = {
8
+ step: string;
9
+ as?: TAs;
10
+ children?: ReactNode;
11
+ } & Omit<ComponentPropsWithoutRef<TAs>, "as" | "children">;
12
+ /**
13
+ * Step para wizard, renderiza somente se ativo e com tipagem dinâmica no as
14
+ */
15
+ export declare function Step<TAs extends ElementType = "div">(props: StepProps<TAs>): import("react/jsx-runtime").JSX.Element | null;
16
+ //# sourceMappingURL=Step.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Step.d.ts","sourceRoot":"","sources":["../../../src/components/Step.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9E;;;;GAIG;AACH,MAAM,MAAM,SAAS,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,IAAI;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,GAAG,CAAC;IACT,QAAQ,CAAC,EAAE,SAAS,CAAC;CACrB,GAAG,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,UAAU,CAAC,CAAC;AAE3D;;GAEG;AACH,wBAAgB,IAAI,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,kDAU1E"}
@@ -0,0 +1,16 @@
1
+ import type { ComponentPropsWithoutRef, ElementType, ReactNode } from "react";
2
+ /**
3
+ * StepProps tipada para permitir definir dinamicamente o componente raíz
4
+ *
5
+ * @template TAs - Tipo do componente (padrão: 'div')
6
+ */
7
+ export type StepProps<TAs extends ElementType = "div"> = {
8
+ step: string;
9
+ as?: TAs;
10
+ children?: ReactNode;
11
+ } & Omit<ComponentPropsWithoutRef<TAs>, "as" | "children">;
12
+ /**
13
+ * Step para wizard, renderiza somente se ativo e com tipagem dinâmica no as
14
+ */
15
+ export declare function Step<TAs extends ElementType = "div">(props: StepProps<TAs>): import("react/jsx-runtime").JSX.Element | null;
16
+ //# sourceMappingURL=Step.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Step.d.ts","sourceRoot":"","sources":["../../../src/components/Step.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9E;;;;GAIG;AACH,MAAM,MAAM,SAAS,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,IAAI;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,GAAG,CAAC;IACT,QAAQ,CAAC,EAAE,SAAS,CAAC;CACrB,GAAG,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,UAAU,CAAC,CAAC;AAE3D;;GAEG;AACH,wBAAgB,IAAI,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,kDAU1E"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useWizardContext } from "../wizards/wizard/context.js";
3
+ /**
4
+ * Step para wizard, renderiza somente se ativo e com tipagem dinâmica no as
5
+ */
6
+ export function Step(props) {
7
+ const { step, as, children, ...rest } = props;
8
+ const { currentStep } = useWizardContext();
9
+ const Component = as || "div";
10
+ if (currentStep !== step) {
11
+ return null;
12
+ }
13
+ return _jsx(Component, { ...rest, children: children });
14
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Wizard = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_hook_form_1 = require("react-hook-form");
6
+ const context_1 = require("../wizards/wizard/context.cjs");
7
+ /**
8
+ * Componente de formulário integrado ao react-hook-form.
9
+ *
10
+ * Permite controle flexível do elemento raiz usando a prop `contextOnly`.
11
+ * - Por padrão, renderiza um `<form>`.
12
+ * - Com `contextOnly`, fornece apenas o contexto do formulário e renderiza o filho customizado, repassando as props do formulário para ele (não renderiza `<form>`).
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * // Modo padrão:
17
+ * <Form methods={formMethods}>
18
+ * <input name="foo" />
19
+ * </Form>
20
+ *
21
+ * // Com contextOnly (ex: usando Radix Slot ou wrapper customizado):
22
+ * <Form methods={formMethods} contextOnly>
23
+ * <CustomFormComponent />
24
+ * </Form>
25
+ * ```
26
+ */
27
+ const Wizard = (props) => {
28
+ const { methods, contextOnly, children, ...formProps } = props;
29
+ if (contextOnly) {
30
+ // Tipagem garante que contextOnly==true implica filhos ReactElement.
31
+ return ((0, jsx_runtime_1.jsx)(react_hook_form_1.FormProvider, { ...methods, children: (0, jsx_runtime_1.jsx)(context_1.WizardProvider, { value: methods, children: children }) }));
32
+ }
33
+ // Padrão: renderiza <form>
34
+ return ((0, jsx_runtime_1.jsx)(react_hook_form_1.FormProvider, { ...methods, children: (0, jsx_runtime_1.jsx)(context_1.WizardProvider, { value: methods, children: (0, jsx_runtime_1.jsx)("form", { onSubmit: props?.onSubmit ? methods.handleSubmit(props.onSubmit) : undefined, ...formProps, children: children }) }) }));
35
+ };
36
+ exports.Wizard = Wizard;